Fast Power + Fast Multiplication

一、快速幂

整数:求a^n,把n化为2*(k1+k2+..+km); 

矩阵:注意矩阵乘法。

复杂度:O(logn)

tip:取了模(根据题目要求)

 1 #include<bits/stdc++.h>
 2 #define mem(a) memset(a,0,sizeof(a))
 3 #define ll long long
 4 using namespace std;
 5 ll mod=1e9;
 6 ll quickpow(ll a,ll n){
 7     ll ans=1;
 8     while(n){
 9         if(n&1)
10             ans=(ans*a)%mod; //取模
11         n>>=1;
12         a=(a*a)%mod;
13     }
14     return  ans%mod;
15 }
16 int main(){
17    cout<<quickpow(2,19);
18    return 0;
19 }
整数
 1 #include<bits/stdc++.h>
 2 #define mem(a) memset(a,0,sizeof(a))
 3 #define ll long long
 4 const int N=1e6+5;
 5 using namespace std;
 6 ll mod=1e9;
 7 struct matrix{
 8   int m[N][N];
 9 };
10 matrix mat_multi(matrix a, matrix b){
11    matrix ans;
12    for(int i=0;i<N;i++){
13     for(int j=0;j<N;j++){
14         ans.m[i][j]=0;
15         for(int k=0;k<N;k++){
16             ans.m[i][j]+=(a.m[i][k]%mod*b.m[k][j]%mod)%mod;
17             ans.m[i][j]%=mod;
18         }
19     }
20    }
21    return ans;
22 }
23 matrix quickpow(matrix a,ll n){
24     matrix ans;
25     for(int i=0;i<N;i++){
26         for(int j=0;j<N;j++){
27             if(i==j) ans.m[i][j]=1;
28             else ans.m[i][j]=0; 
29     //初始化为单位矩阵,类比整型时的1;单位矩阵*矩阵A=矩阵A
30         }
31     }
32     while(n!=0){
33         if(n&1)
34             ans=mat_multi(a,ans); 
35         n>>=1;
36         a=mat_multi(a,a);
37     }
38     return  ans;
39 }
矩阵

二、快速乘

O(logn)的思想和快速幂很像,把b二进制化,如果是1,就乘上a,a也要不断地乘二,相当于a*(2^i)。就像下面这张图

说实话,O(1)的真没看懂,来自这两篇🕵️‍♀️💨

 1 ll qmul(ll a,ll b,ll mod)//计算a*b%mod
 2 {
 3     ll ans=0;
 4     while(b>0)
 5     {
 6         if(b&1) ans=(ans+a)%mod;
 7         a=(a<<1)%mod; //模仿二进制加法
 8         b>>=1;
 9     }
10     return ans;
11 }
O(logn)
1 ll qmul(ll a,ll b,ll mod)//计算a*b%mod
2 {
3     ll x=(ld)a/mod*b;
4     ll ans=(ull)a*b-(ull)x*mod;
5     return (ans+mod)%mod;
6 }
O(1) // 1
1 ll qmul(ll a,ll b,ll mod)//计算a*b%mod
2 {
3     return (a*b-(ll)((ld)a/mod*b)*mod+mod)%mod;
4 }
O(1) // 2

 

三、题目

①基础

(1)http://noi.openjudge.cn/ch0204/2991/

关键是循环节

tips:string->int:m=atoi(n.c_str());  

         去字符串:substr(起始,长度)

 1 #include<bits/stdc++.h>
 2 #define mem(a) memset(a,0,sizeof(a))
 3 #define ll long long
 4 #define inf 0x3f3f3f3f
 5 const int N=1e6+5;
 6 using namespace std;
 7 ll mod=1e4;
 8 ll Mod=500;
 9 ll ans[205];
10 ll quickpow(ll a,ll n){
11    ll ans=1;
12    while(n){
13       if(n&1) ans=(ans*a)%mod;
14       n>>=1;
15       a=(a*a)%mod;
16    }
17    return ans%mod;
18 }
19 int main(){
20    int k;
21 
22    string n;
23    cin>>k;
24    while(k--){
25     cin>>n;
26     int len=n.size();
27     int m;
28     if(len>5){
29         string n1=n.substr(len-4,4); //起始,长度
30         m=atoi(n1.c_str()); //返回一个const *char,内容相同
31     }
32     else
33     m=atoi(n.c_str());
34     cout<<quickpow(2011,m%Mod)<<endl;
35    }
36    return 0;
37 }
2991:2011

 

        

posted @ 2019-06-28 21:58  XXrl  阅读(184)  评论(0编辑  收藏  举报