我真是醉了,快速幂和矩阵快速幂T飞了,竟然还有光速幂和矩阵光速幂。
下面给个光速幂和矩阵光速幂板子。
普通光速幂:
1 #include2 #define ll long long 3 #define scan(i) scanf("%d",&i) 4 #define scand(i) scanf("%lf",&i) 5 #define scanl(i) scanf("%lld",&i) 6 #define f(i,a,b) for(int i=a;i<=b;i++) 7 #define pb(i) push_back(i) 8 #define ppb pop_back() 9 #define pf printf 10 #define dbg(args...) cout<<#args<<" : "< 11 #define RG register 12 using namespace std; 13 int t,n; 14 const ll mod=1e9+7; 15 const ll x1=94153035; 16 const ll x2=905847205; 17 const ll x3=64353223;//x3=x1^65536%mod 18 const ll x4=847809841;//x4=x2^65536%mod 19 const int maxn=65536;//maxn>sqrt(mod) 20 int f_1[maxn+5], f_2[maxn+5], f_3[maxn+5], f_4[maxn+5]; 21 //f_3[i]保存x1^(i<<16),f_1[i]保存x1^i 22 //f_4[i]保存x2^(i<<16),f_2[i]保存x2^i 23 inline int Pow_1(int x) { return 1ll * f_3[x >> 16] * f_1[x & 65535] % mod; } 24 //Pow_1返回x1^x%mod 25 inline int Pow_2(int x) { return 1ll * f_4[x >> 16] * f_2[x & 65535] % mod; } 26 //Pow_2返回x2^x%mod 27 int main(){ 28 f_1[0] = f_2[0] = f_3[0] = f_4[0] = 1; 29 for(RG int i = 1; i < maxn; i++) f_1[i] = 1ll * f_1[i - 1] * x1 % mod; 30 for(RG int i = 1; i < maxn; i++) f_2[i] = 1ll * f_2[i - 1] * x2 % mod; 31 for(RG int i = 1; i < maxn; i++) f_3[i] = 1ll * f_3[i - 1] * x3 % mod; 32 for(RG int i = 1; i < maxn; i++) f_4[i] = 1ll * f_4[i - 1] * x4 % mod; 33 return 0; 34 }
矩阵光速幂:
1 #include2 #define ll long long 3 #define scan(i) scanf("%d",&i) 4 #define scand(i) scanf("%lf",&i) 5 #define scanl(i) scanf("%lld",&i) 6 #define f(i,a,b) for(int i=a;i<=b;i++) 7 #define pb(i) push_back(i) 8 #define ppb pop_back() 9 #define pf printf 10 #define dbg(args...) cout<<#args<<" : "< 11 #define RG register 12 using namespace std; 13 int t,n; 14 const int maxn=65536; 15 const int N=2; 16 const ll mod=998244353; 17 ll f_1[maxn+5][N][N], f_2[maxn+5][N][N]; 18 //f_1[i]存储base1^i,f_2[i]存储base1^[i<<16]; 19 ll base1[N][N]={ 20 1,1, 21 1,1 22 }; 23 ll base2[N][N]={//base2=base1^65536%mod 24 1,1, 25 1,1 26 }; 27 ll tmp[N][N]; 28 ll qpow(ll x,ll i){//ans=x^i 29 ll ans = 1; 30 while(i) 31 { 32 if(i&1) ans = (ans*x)%mod; 33 i >>= 1; 34 x = (x*x)%mod; 35 } 36 return ans; 37 } 38 void multi(ll c[][N],ll a[][N],ll b[][N]){//c=axb 39 //memset(c,0,sizeof c); 40 for(ll i=0;i ){ 41 for(ll j=0;j ){ 42 for(ll k=0;k ) 43 c[i][j]+=a[i][k]*b[k][j]; 44 c[i][j]%=mod; 45 } 46 } 47 } 48 ll res[N][N]; 49 void print(){ 50 for(int i=0;i ){ 51 for(int j=0;j ){ 52 cout< " "; 53 } 54 cout<<endl; 55 } 56 } 57 int main(){ 58 for(int i=0;i 0][i][i]=f_2[0][i][i]=1; 59 for(RG int i = 1; i < maxn; i++) multi(f_1[i],f_1[i-1],base1); 60 for(RG int i = 1; i < maxn; i++) multi(f_2[i],f_2[i-1],base2); 61 }
既然名字叫光速幂,肯定是很快的。
快速幂复杂度O(Tlogn),T是查询次数,n是幂次数;
光速幂复杂度O(T+sqrt(m)),T是查询次数,m是取得mod;
一般来说,sqrt(mod)最多在1e5,所以应该快上不少。
以上。