Description
给定正整数n和如下方程
x xor 3x=2x
1. 求不大于n的正整数中有多少个解
2. 求不大于2^n的正整数中有多少个解,膜10^9+7
注意第一个问题的解不要mod 10^9+7
1<=N<=10^18
1<=T<=1000
Solution
方程等价于2x xor x=3x-x,也就是解一定满足在二进制下没有相邻的位同时为1,那么数位dp即可
注意到第二问是没有限制的,实际上是斐波那契数列的第n+2项
Code
#include <stdio.h>
#include <string.h>
#define rep(i,st,ed) for (int i=st;i<=ed;++i)
#define drp(i,st,ed) for (int i=st;i>=ed;--i)
#define fill(x,t) memset(x,t,sizeof(x))
typedef long long LL;
const int MOD=1000000007;
struct matrix {
int a[3][3];
matrix operator *(matrix b) {
matrix c; fill(c.a,0);
rep(i,1,2) rep(j,1,2) {
rep(k,1,2) (c.a[i][j]+=(LL)a[i][k]*b.a[k][j]%MOD)%=MOD;
}
return c;
}
} A,tmp;
LL f[64][2],num[64];
void solve1(LL x) {
num[0]=0;
for (LL i=x;i;i/=2) num[++num[0]]=i%2;
LL ret=0;
drp(i,num[0]-1,1) {
rep(j,0,num[i]-1) ret+=f[i][j];
if (num[i]+num[i+1]==2) break;
}
rep(i,1,num[num[0]]-1) ret+=f[num[0]][i];
rep(i,1,num[0]-1) ret+=f[i][1];
printf("%lld\n", ret);
}
matrix ksm(matrix x,LL dep) {
matrix ret=x; dep-=1;
while (dep) {
if (dep&1) ret=ret*x;
x=x*x; dep/=2;
}
return ret;
}
void solve2(LL x) {
x+=2;
A.a[1][1]=0; A.a[1][2]=A.a[2][1]=A.a[2][2]=1;
A=ksm(A,x);
printf("%d\n", A.a[1][2]);
}
int main(void) {
f[1][0]=f[1][1]=1;
rep(i,2,63) {
f[i][0]=f[i-1][0]+f[i-1][1];
f[i][1]=f[i-1][0];
}
int T; scanf("%d",&T);
while (T--) {
LL n; scanf("%lld",&n);
solve1(n+1);
solve2(n);
}
return 0;
}