传送门:https://nanti.jisuanke.com/t/41355
题意:
给定q,N1,求F[N1] xor F[N2] xor ··· xor F[Nq]。其中,Ni=N(i-1) xor (F[N(i-1)]*F[N(i-1)])。
分析:
显然,要用到矩阵快速幂来计算F[n],可推得
。
但是写完发现如果q>
会超时。想了一下午如何加速,最后发现始终突破不了
。最终尝试用10进制的矩阵快速幂,但还是不行。比赛结束后在某个群里看到有人说这题加个if(q>100000) q=100000就行了。因为异或下去某个Ni=0时后面的结果保持不变。(很难受~~)
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=998244353;
const int maxn=2;
struct mat{
ll m[maxn][maxn];
}unit;
mat operator *(mat a,mat b){
mat res;
memset(res.m,0,sizeof(res.m));
for(int i=0;i<maxn;i++){
for(int j=0;j<maxn;j++){
for(int k=0;k<maxn;k++){
res.m[i][j]=(res.m[i][j]+a.m[i][k]*b.m[k][j])%mod;
}
}
}
return res;
}
void init(){
for(int i=0;i<maxn;i++)
unit.m[i][i]=1;
}
mat pow_mat(mat x,ll n){
if(n>499122176)
n%=499122176;
int v[20],j=0;
ll h=n;
while(h){
v[++j]=h%10;
h/=10;
}
mat res=unit;
for(int k=1;k<=j;k++){
for(int i=1;i<=v[k];i++){
res=res*x;
}
mat c[2];
x=x*x;
c[0]=x*x;
c[1]=c[0]*c[0];
x=x*c[1];
}
return res;
}
int main(){
ll q,n;
init();
scanf("%lld %lld",&q,&n);
if(q>100000)
q=100000;
mat a;
a.m[0][0]=3;
a.m[0][1]=2;
a.m[1][0]=1;
a.m[1][1]=0;
ll t,ans=0,k;
mat res;
for(int i=1;i<=q;i++){
res=pow_mat(a,n-1);
t=res.m[0][0];
if(t!=0){
ans=ans xor t;
n=((t*t)) xor n;
}
}
printf("%lld\n",ans);
return 0;
}