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

 

posted @ 2019-09-09 01:10  nervending  阅读(259)  评论(0编辑  收藏  举报