题意:https://nanti.jisuanke.com/t/41355 给出N1,计算公式:A=F(N)Ni=Ni-1 ^ (A*A),F为类斐波那契需要矩阵快速幂的递推式。 求第k个N。 思路: 发现从大约1e5个数开始N交替出现,到一定位置%2即
题意:https://nanti.jisuanke.com/t/41355
给出N1,计算公式:A=F(N)Ni=Ni-1 ^ (A*A),F为类斐波那契需要矩阵快速幂的递推式。
求第k个N。
思路:
发现从大约1e5个数开始N交替出现,到一定位置%2即可。(or正解:https://blog.csdn.net/qq_41848675/article/details/100667808 or
https://blog.csdn.net/jk_chen_acmer/article/details/100635672 or map记忆化)
1 #include<bits/stdc++.h> 2 using namespace std; 3 //const int maxn=1000005; 4 using namespace std; 5 typedef long long ll; 6 const int N = 2;//矩阵大小 7 //ll k; 8 const long long mod=(long long )998244353; 9 struct Mat 10 { 11 ll mat[N][N]; 12 Mat operator*(const Mat a)const 13 { 14 Mat b; memset(b.mat, 0, sizeof(b.mat)); 15 for (int i = 0; i < N; i++) 16 for (int j = 0; j < N; j++) 17 for (int k = 0; k < N; k++) 18 b.mat[i][j] = (b.mat[i][j] + (mat[i][k]) *(a.mat[k][j])) % mod; 19 return b; 20 } 21 }; 22 23 ll phi(ll x)//求欧拉 24 { 25 ll res=x; 26 for(ll i=2;i*i<=x;i++) 27 { 28 if(x%i==0) 29 { 30 res=res/i*(i-1); 31 while(x%i==0) x/=i; 32 } 33 } 34 if(x>1) res=res/x*(x-1); 35 return res; 36 } 37 Mat Pow(Mat m, ll k) 38 { 39 //if(k==1) return 1; 40 Mat ans; 41 memset(ans.mat, 0, sizeof(ans.mat)); 42 for (int i = 0; i < N; i++) 43 ans.mat[i][i] = 1; 44 while (k) 45 { 46 if (k & 1) ans = ans*m; 47 k >>= 1; 48 m = m*m; 49 } 50 return ans; 51 } 52 53 ll que[4*2000000]; 54 int head=0,tail=1 ; 55 int main() { 56 57 ll phi_mod=phi(mod); 58 Mat m; 59 int q; 60 ll n,ans; 61 scanf("%d%lld",&q,&n); 62 //printf("\n%d %lld\n",q,n); 63 Mat f; 64 m.mat[0][0]=3;m.mat[0][1]=2; 65 m.mat[1][0]=1;m.mat[1][1]=0; 66 f.mat[0][0]=1;//x1 67 f.mat[1][0]=0;//x0 68 f = Pow(m, (n-1)%phi_mod)*f; 69 ans=f.mat[0][0]; 70 //printf("%lld %lld\n",n,ans); 71 que[head]=ans; 72 73 74 75 76 //printf("%lld",f.mat[0][0]); 77 /* 78 * 10000000 1000000000000000000 79 * */ 80 for (register int i = 2; i <= q; i++) { 81 //init(m); 82 //memset(f.mat, 0, sizeof(f.mat)); 83 n = n ^ (f.mat[0][0] * f.mat[0][0]); 84 85 if (n == 0) { 86 f.mat[0][0] = 0; 87 } else if (n == 1) { 88 f.mat[0][0] = 1; 89 } else { 90 m.mat[0][0] = 3; 91 m.mat[0][1] = 2; 92 m.mat[1][0] = 1; 93 m.mat[1][1] = 0; 94 f.mat[0][0] = 1;//x1 95 f.mat[1][0] = 0;//x0 96 97 f = Pow(m, (n - 1) % phi_mod) * f; 98 99 } 100 ans = ans ^ f.mat[0][0]; 101 //printf("%lld %lld\n", n, ans); 102 103 104 que[tail++]=ans; 105 if(tail-head>4) 106 { 107 head++; 108 if(que[head]==que[head+2]&&que[head+1]==que[head+1+2]) 109 { 110 int tmp=q-i; 111 if(tmp%2) 112 { 113 ans=que[head]; 114 } 115 else 116 { 117 ans=que[head+1]; 118 } 119 break; 120 } 121 } 122 123 124 } 125 printf("%lld\n",ans); 126 return 0; 127 } 128 129 /* 130 * 858251072 131 * 132 * 245284867829898842 447003402 133 485245887812443738 1008229130 134 * 135 * 136 * 137 * 138 * */