光速幂

我真是醉了,快速幂和矩阵快速幂T飞了,竟然还有光速幂和矩阵光速幂。

下面给个光速幂和矩阵光速幂板子。

普通光速幂:

 1 #include<bits/stdc++.h>
 2 #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<<" : "<<args<<endl;
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 #include<bits/stdc++.h>
 2 #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<<" : "<<args<<endl;
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<n;i++){
41         for(ll j=0;j<n;j++){
42             for(ll k=0;k<n;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<N;i++){
51         for(int j=0;j<N;j++){
52             cout<<res[i][j]<<" ";
53         }
54         cout<<endl;
55     }
56 }
57 int main(){
58     for(int i=0;i<N;i++) f_1[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,所以应该快上不少。

以上。

猜你喜欢

转载自www.cnblogs.com/St-Lovaer/p/11504899.html