BZOJ3329 Xorequ 数位dp
noi第一ysy大佬题解。
1 #include<cstring> 2 #include<cmath> 3 #include<algorithm> 4 #include<cstdio> 5 #include<iostream> 6 7 #define mod 1000000007 8 #define ll long long 9 using namespace std; 10 inline ll read() 11 { 12 ll x=0,f=1;char ch=getchar(); 13 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} 14 while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();} 15 return x*f; 16 } 17 18 ll n; 19 ll f[64][2][2],bin[67]; 20 ll a[3][3],b[3][3],ans[3][3],t[3][3],g[3]; 21 22 void mul(ll b) 23 { 24 ans[1][1]=1,ans[2][2]=1;ans[1][2]=ans[2][1]=0; 25 while(b) 26 { 27 if(b&1) 28 { 29 memset(t,0,sizeof(t)); 30 for (int i=1;i<=2;i++) 31 for (int j=1;j<=2;j++) 32 for (int k=1;k<=2;k++) 33 (t[i][j]+=ans[i][k]*a[k][j])%=mod; 34 for (int i=1;i<=2;i++) 35 for (int j=1;j<=2;j++) 36 ans[i][j]=t[i][j]; 37 } 38 memset(t,0,sizeof(t)); 39 for (int i=1;i<=2;i++) 40 for (int j=1;j<=2;j++) 41 for (int k=1;k<=2;k++) 42 (t[i][j]+=a[i][k]*a[k][j])%=mod; 43 for (int i=1;i<=2;i++) 44 for (int j=1;j<=2;j++) 45 a[i][j]=t[i][j]; 46 b>>=1; 47 } 48 } 49 int main() 50 { 51 int T=read(); 52 bin[0]=1; 53 for (ll i=1;i<=63;i++) 54 bin[i]=bin[i-1]<<1; 55 while(T--) 56 { 57 memset(f,0,sizeof(f)); 58 n=read(); 59 ll x=0;while(bin[x]<=n)x++;x--; 60 f[x][1][1]=1,f[x][0][0]=1; 61 for (ll i=x-1;i>=0;i--) 62 { 63 if(n&bin[i]) 64 { 65 f[i][1][1]=f[i+1][0][1]; 66 f[i][1][0]=f[i+1][0][0]; 67 f[i][0][0]=f[i+1][1][1]+f[i+1][1][0]+f[i+1][0][1]+f[i+1][0][0]; 68 } 69 else 70 { 71 f[i][1][0]=f[i+1][0][0]; 72 f[i][0][0]=f[i+1][1][0]+f[i+1][0][0]; 73 f[i][0][1]=f[i+1][1][1]+f[i+1][0][1]; 74 } 75 } 76 printf("%lld\n",f[0][0][0]+f[0][0][1]+f[0][1][0]+f[0][1][1]-1); 77 g[1]=2,g[2]=3; 78 if(n<=2) 79 { 80 printf("%lld\n",g[n]); 81 continue; 82 } 83 a[1][1]=0,a[1][2]=1,a[2][1]=1,a[2][2]=1; 84 mul(n-2); 85 printf("%lld\n",(ans[1][2]*2+ans[2][2]*3)%mod); 86 } 87 }