A
dfs暴力得到
{a[n]}
={1 1 2 2 4 4 6 6 10 10 14 14 20 20 26 26 36 36 46 46 60 60 74 74 94 94 114 114 140 140 166 166 202 202 238 238 284 284 330 330 390 390 450 450 524 524 598 598 692 692 ……}
发现对偶数项做差得到了原数列
{a[n]}={a[2k]−a[2⋅(k−1)]}
那么就不难得到递推公式
a[i + 1] = a[i] = (a[i / 2] + a[i - 1]) % 1000000000;
注:下标都是从0开始的
#include<stdio.h>
int dp[1<<20] = {1,1,2,2,4,4};
void init() {
for(int i = 4; i < 1<<20; i += 2) {
dp[i + 1] = dp[i] = (dp[i / 2] + dp[i - 1]) % 1000000000;
}
}
int main()
{
init();
int n;
while(scanf("%d", &n) != EOF) {
printf("%d\n", dp[n]);
}
return 0;
}
B
当然是xjb写了
#include<stdio.h>
#include<map>
#include<algorithm>
using namespace std;
int d[1<<16], w[1<<16], id[1<<16];
map<int, int> mp;
map<int,int>::iterator it;
int main()
{
int n, m, sz = 1, x;
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; ++i) {
scanf("%d", &x);
if(mp[x]) continue;
mp[x] = i;
}
it = mp.begin();
while(it != mp.end()) {
w[sz] = it->first;
id[sz] = it->second;
if(sz > 1 && id[sz] > id[sz - 1]) id[sz] = id[sz - 1];
++sz;
it ++;
}
w[sz] = 1<<30;
int use = n, ans = 0;
for(int i = 0; i < m; ++i) {
scanf("%d", &x);
int pos = (int)(lower_bound(w, w + sz + 2, x) - w) - 1;
if(use <= 0) continue;
if(pos == 0) --use, ++ans;
else if(pos == sz) use = 0;
else {
if(id[pos] > use) --use;
else use = id[pos] - 2;
if(use >= 0) ++ans;
}
}
printf("%d\n", ans);
return 0;
}
C
或运算是对于二进制而言的,我们考虑二进制即可
将所有数分两类:
一类是无论或上谁都不可能为x
一类是或运算后可能为x,我们考虑在这些数中去除最少个即可。
#include<stdio.h>
#include<algorithm>
using namespace std;
int cnt[2][63];
void add(long long n, int op) {
for(int i = 0; i <= 62; ++i) {
cnt[op][i] += n>>i&1;
}
}
int main()
{
int n;
long long x, X;
scanf("%d%lld", &n, &x);
add(x, 0);
X = x;
for(int i = 0; i < n; ++i) {
scanf("%lld", &x);
if(!(x&~X)) add(x, 1);
}
int ans = 1<<30;
for(int i = 0; i <= 62; ++i) {
if(cnt[0][i])
ans = min(ans, cnt[1][i]);
}
printf("%d\n", ans);
return 0;
}
G
感觉会爆精度啊,然而并没有(我用了高精度模板,然而错了,不知道是不是模板问题)
#include<stdio.h>
typedef long long LL;
LL exGcd(LL a,LL b,LL &x,LL &y){
if (b==0){
x=1,y=0;
return a;
}
LL q=exGcd(b,a%b,y,x);
y-=a/b*x;
return q;
}
LL CRT(int *m,int *a,int n){
LL M=1,ans=0,x,t_i;
for (int i=1;i<=n;i++) M*=m[i];
for (int i=1;i<=n;i++){
LL M_i=M/m[i];
exGcd(m[i],M_i,x,t_i); //求 M_i 模 m[i] 的逆元 t_i
ans=(ans+a[i]*t_i%M*M_i%M)%M;
}
return (ans+M)%M;
}
int main()
{
int n, x[1<<4], y[1<<4];
scanf("%d", &n);
for(int i = 1; i <= n; ++i) {
scanf("%d %d", x + i, y + i);
}
LL ans = CRT(x, y, n);
printf("%lld\n", ans);
return 0;
}
(没写完,既然写了,就发出来