A:
本意是當簽到題,但是可能低估了這題的難度
在線標記處理二分查找
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1000005;
int n, w[maxn];
bool vis[maxn];
set<int> a;
set<int>::iterator it;
inline int read() {
int ret = 0, f = 1;
char ch = getchar();
while (ch < '0' || ch > '9') {
if (ch == '-')
f = -f;
ch = getchar();
}
while (ch >= '0' && ch <= '9') ret = (ret << 3) + (ret << 1) + ch - '0', ch = getchar();
return ret * f;
}
int main() {
n = read();
for (int i = 1; i <= n; i++) {
char ch = getchar();
int x;
while (ch != 'O' && ch != 'I' && ch != '?') ch = getchar();
if (ch == '?')
a.insert(i);
else if (ch == 'I') {
x = read();
if (vis[x]) {
it = a.upper_bound(w[x]);
if (it == a.end() || (*it > i))
return printf("%d\n", i), 0;
else
a.erase(it);
}
vis[x] = 1;
w[x] = i;
} else {
x = read();
if (!vis[x]) {
it = a.upper_bound(w[x]);
if (it == a.end() || (*it > i))
return printf("%d\n", i), 0;
else
a.erase(it);
}
vis[x] = 0, w[x] = i;
}
}
printf("-1\n");
return 0;
}
B題
本意通過素數篩求,但是有一組測試數據太大沒放上去,導致別的做法可以卡過去,因爲測評機的原因,我開了3s,降低了難度係數
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e8 + 110, mod = 100000007;
int n, pri[10000000], tot = 0;
long long ans = 1;
bool hs[maxn];
void shai() {
hs[1] = 1;
for (int i = 2; i <= n; ++i) {
if (!hs[i]) {
pri[++tot] = i;
for (long long k = i; k <= n; k *= i) ans = (ans * i) % mod;
}
for (int j = 1; j <= tot && i * pri[j] <= n; ++j) {
hs[i * pri[j]] = 1;
if (!(i % pri[j]))
break;
}
}
}
int main() {
scanf("%d", &n);
shai();
printf("%d\n", ans);
return 0;
}
C:
邏輯題,其實沒啥東西。。
long long a[1000010], b[1000010], v, n;
int main() {
scanf("%d", &n);
b[0] = 1;
for (int i = 1; i <= n; i++) {
scanf("%lld", &a[i]);
(v += a[i]) %= n;
if (b[v]) {
for (int j = b[v]; j <= i; j++) printf("%d %d\n", j, a[j]);
return 0;
}
b[v] = i + 1;
}
return 0;
}
D:
min_25板子題,其實我一開始沒考慮板子,後來cc提到的
#include <bits/stdc++.h>
#define ri register int
using namespace std;
const int N = 1e6 + 5;
typedef long long ll;
ll f1[N], f2[N], n;
int lim;
int main() {
cin >> n;
lim = sqrt(n);
for (ri i = 1; i <= lim; ++i) f1[i] = i - 1, f2[i] = n / i - 1;
for (ri p = 2; p <= lim; ++p) {
if (f1[p] == f1[p - 1])
continue;
for (ri i = 1; i <= lim / p; ++i) f2[i] -= f2[i * p] - f1[p - 1];
for (ri i = lim / p + 1; (ll)i <= n / (ll)p / (ll)p && i <= lim; ++i)
f2[i] -= f1[n / i / p] - f1[p - 1];
for (ri i = lim; i >= (ll)p * p; --i) f1[i] -= f1[i / p] - f1[p - 1];
}
cout << f2[1];
return 0;
}
E:斐波那契矩陣快速冪
這是我的標程序,可以記下來當板子,但是不是很好理解,建議別看。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll,ll> pll;
const int mod=1e9+7;
pll operator *(const pll &a,const pll &b)
{
return make_pair((a.first*b.first+a.second*b.second)%mod,(a.first*b.second+a.second*b.first+a.second*b.second)%mod);
}
ll F(ll y)
{
pll ans=make_pair(1,0),x=make_pair(0,1);
while(y)
{
if(y&1) ans=ans*x;
x=x*x;
y/=2;
}
return ans.first+ans.second;
}
int main()
{
ll n;
cin>>n;
cout<<F(n-1)*F(n)%mod;
return 0;
}
這是常規做法
學這個吧
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const LL mod=1e9+7;
LL n,p;
struct node
{
LL m[3][3];
node(){
memset(m,0,sizeof(m));
}
friend node operator *(node x,node y){
node t;
for(int i=1;i<=2;i++){
for(int j=1;j<=2;j++){
t.m[i][j]=0;
}
}
for(int i=1;i<=2;i++){
for(int j=1;j<=2;j++){
for(int k=1;k<=2;k++){
t.m[i][j]+=((x.m[i][k]%mod)*(y.m[k][j]%mod))%mod;
}
}
}
return t;
}
}a,ans;
node binary(node x,LL y)
{
while(y){
if(y&1) ans=ans*x;
x=x*x;
y>>=1;
}
return ans;
}
void Init()
{
a.m[1][1]=1;
a.m[1][2]=1;
a.m[2][1]=1;
a.m[2][2]=0;
ans.m[1][1]=1;
ans.m[1][2]=1;
}
int main()
{
Init();
LL n;scanf("%lld",&n);
n++;
if(n<=2) printf("1\n");
else{
node t=binary(a,n-2);
printf("%lld\n",((t.m[1][1]%mod)*(t.m[1][2]%mod))%mod);
}
return 0;
}