x^2x=3x,x+2x=3x。而异或是不进位的加法。
所以x+2x不能进位。也就是说x中没有相邻的两个1。
对于第一问可以数位dp,对第二问可以矩阵快速幂。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define mod 1000000007 using namespace std; long long t,n,ans1,ans2,ret=0,bit[100],dp[100][2]; struct matrix { long long t[3][3]; friend matrix operator *(const matrix &x,const matrix &y) { matrix ans; for (long long i=1;i<=2;i++) for (long long j=1;j<=2;j++) ans.t[i][j]=0; for (long long i=1;i<=2;i++) for (long long j=1;j<=2;j++) for (long long k=1;k<=2;k++) ans.t[i][j]=(ans.t[i][j]+(x.t[i][k]*y.t[k][j])%mod)%mod; return ans; } }base[100],ans; void get_bit(long long x) { ret=0; while (x) {bit[++ret]=x&1;x>>=1;} } long long digit_dp(long long now,long long pre,bool flag) { if (!now) return 1; if (!flag && dp[now][pre]) return dp[now][pre]; long long ret=0,up=flag?bit[now]:1; for (long long i=0;i<=up;i++) { if (pre && i) continue; ret+=digit_dp(now-1,i,flag && (i==up)); } if (!flag) dp[now][pre]=ret; return ret; } void work1() { get_bit(n); ans1=digit_dp(ret,0,1); } void work2() { ans.t[1][1]=ans.t[1][2]=1; long long ret=0,y=n-1; while (y) { if (y&1) ans=ans*base[ret]; ret++;y>>=1; } ans2=(ans.t[1][1]+ans.t[1][2]+1)%mod; } int main() { scanf("%lld",&t); base[0].t[1][1]=base[0].t[1][2]=base[0].t[2][1]=1;base[0].t[2][2]=0; for (long long i=1;i<=64;i++) base[i]=base[i-1]*base[i-1]; for (long long i=1;i<=t;i++) { scanf("%lld",&n); work1();work2(); printf("%lld\n%lld\n",ans1-1,ans2-1); } return 0; }