南昌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;
}

浙公网安备 33010602011771号