BZOJ 3329 Xorequ
Description
Input
第一行一个正整数,表示数据组数据 ,接下来T行
每行一个正整数N
Output
2*T行
第2*i-1行表示第i个数据中问题一的解,
第2*i行表示第i个数据中问题二的解,
Sample Input
1
1
1
Sample Output
1
2
2
HINT
x=1与x=2都是原方程的根,注意第一个问题的解
不要mod 10^9+7
1<=N<=10^18
1<=T<=1000
条件转化为二进制相邻两位不能同为1
第一问大小有限制,用数位dp
第二问直接矩阵快速幂
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 using namespace std; 7 typedef long long lol; 8 struct Matrix 9 { 10 lol a[2][2]; 11 }Mat,ans; 12 int Mod=1e9+7; 13 Matrix operator *(const Matrix &a,const Matrix &b) 14 {int i,j,k; 15 Matrix res; 16 memset(res.a,0,sizeof(res.a)); 17 for (i=0;i<=1;i++) 18 { 19 for (j=0;j<=1;j++) 20 { 21 for (k=0;k<=1;k++) 22 { 23 res.a[i][j]+=a.a[i][k]*b.a[k][j]%Mod; 24 res.a[i][j]%=Mod; 25 } 26 } 27 } 28 return res; 29 } 30 lol f[61][2][2],lim; 31 lol n,s,a[61],len; 32 lol dfs(int pos,int pre,int flag,int k) 33 {int i; 34 if (pos<0) return 1; 35 if (k&&f[pos][pre][flag]!=-1) return f[pos][pre][flag]; 36 int ed=1; 37 lol cnt=0; 38 if (flag) ed=(n>>pos)&1; 39 for (i=0;i<=ed;i++) 40 { 41 if (pre==1&&i==1) continue; 42 cnt+=dfs(pos-1,i,flag&&(i==ed),k||(i!=0)); 43 } 44 if (k) f[pos][pre][flag]=cnt; 45 return cnt; 46 } 47 void qpow(lol k) 48 { 49 Matrix res; 50 res.a[0][0]=1;res.a[0][1]=0; 51 res.a[1][1]=1;res.a[1][0]=0; 52 while (k) 53 { 54 if (k&1) res=res*Mat; 55 Mat=Mat*Mat; 56 k>>=1; 57 } 58 ans=ans*res; 59 } 60 int main() 61 {lol i,T; 62 cin>>T; 63 while (T--) 64 { 65 scanf("%lld",&n); 66 memset(f,-1,sizeof(f)); 67 s=n;len=0; 68 memset(a,0,sizeof(a)); 69 for (;s;s/=2) 70 a[++len]=s&1; 71 printf("%lld\n",dfs(len,0,1,0)-1); 72 memset(ans.a,0,sizeof(ans.a)); 73 Mat.a[0][0]=1;Mat.a[0][1]=1; 74 Mat.a[1][0]=1;Mat.a[1][1]=0; 75 ans.a[0][0]=1;ans.a[0][1]=1; 76 qpow(n-1); 77 if (n==1) printf("2\n"); 78 else 79 printf("%lld\n",(ans.a[0][0]+ans.a[0][1])%Mod); 80 } 81 }