南昌icpc网络选拔赛 H题 K进制加速矩阵快速幂
https://nanti.jisuanke.com/t/41355
一眼矩阵快速幂,但是显然过不去,$1e7*log(1e18)$,矩阵很小.
然后开始优化:
1.和斐波那契一样,打表可以发现模运算下,循环节为$499122176$,快速幂从$1e7*log(1e18)$变成$1e7*log(4e8)$快了一些
2.和快速幂类似,我们发现,如果预处理出$1,2,....sqrt(499122176)-1$次幂下的系数矩阵和$sqrt(499122176),2sqrt(499122176)..sqrt(499122176)*(sqrt(499122176)-1))$次幂下的系数矩阵
那么我们可以快速凑出任何的一个我们需要的系数矩阵,
嗯,就是$O(1)$得到,最终复杂度$1e7+5e4$
跑得还可以...
#include<bits/stdc++.h> using namespace std; const int mod=998244353,mxpw=22400; struct node {int a,b,c,d;}m_pow[2][mxpw],tmp,xishu={3,2,1,0}; inline node mul(const node &x,const node &y) { return {(1ll*x.a*y.a+1ll*x.b*y.c)%mod,(1ll*x.a*y.b+1ll*x.b*y.d)%mod, (1ll*x.c*y.a+1ll*x.d*y.c)%mod,(1ll*x.c*y.b+1ll*x.d*y.d)%mod}; } int getans(int n) {return mul(m_pow[0][n%mxpw],m_pow[1][n/mxpw]).a;} signed main() { m_pow[0][0]=m_pow[1][0]={1,0,0,1}; for(int j=1;j<=mxpw-1;++j) m_pow[0][j]=mul(m_pow[0][j-1],xishu); m_pow[1][1]=mul(m_pow[0][mxpw-1],xishu); for(int j=2;j<=mxpw-1;++j) m_pow[1][j]=mul(m_pow[1][j-1],m_pow[1][1]); int ans=0,q,res;long long n;cin>>q>>n; while(q--) { res=getans(n%499122176-1); ans^=res; n^=(1ll*res*res); } cout<<ans; }