[bzoj3329]Xorque
首先将问题转化为2x^x=3x,那么相当于让x右移一位和原数的1不相交,即不含有相邻的1,第一个问题可以直接数位dp,第二个问题可以类似dp+矩乘优化即可
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 #define mod 1000000007 5 struct ji{ 6 int a[2][2]; 7 ji operator * (const ji &b){ 8 ji c; 9 for(int i=0;i<2;i++) 10 for(int j=0;j<2;j++) 11 c.a[i][j]=(1LL*a[i][0]*b.a[0][j]+1LL*a[i][1]*b.a[1][j])%mod; 12 return c; 13 } 14 }p; 15 int t,ans,a[101]; 16 ll n,f[101][2]; 17 ll dfs(int k,int t,int p){ 18 if (!k)return 1; 19 if ((p)&&(f[k][t]))return f[k][t]; 20 int ma=1; 21 ll ans=0; 22 if (!p)ma=a[k]; 23 for(int i=0;i<=ma;i++) 24 if ((!i)||(!t))ans+=dfs(k-1,i,p|(i<ma)); 25 if (p)f[k][t]=ans; 26 return ans; 27 } 28 ll calc(ll k){ 29 a[0]=0; 30 memset(f,0,sizeof(f)); 31 while (k){ 32 a[++a[0]]=k%2; 33 k/=2; 34 } 35 return dfs(a[0],0,0); 36 } 37 ji ksm(ji n,ll m){ 38 if (m==1)return n; 39 ji s=ksm(n,m>>1); 40 s=s*s; 41 if (m&1)s=s*n; 42 return s; 43 } 44 int main(){ 45 scanf("%d",&t); 46 while (t--){ 47 scanf("%lld",&n); 48 printf("%lld\n",calc(n)-1); 49 if (n==1){ 50 printf("2\n"); 51 continue; 52 } 53 p=ksm(ji{1,1,1,0},n-1); 54 ans=0; 55 for(int i=0;i<2;i++) 56 for(int j=0;j<2;j++)ans=(ans+p.a[i][j])%mod; 57 printf("%d\n",ans); 58 } 59 }