28 条题解

  • 11
    @ 2022-3-16 16:29:12

    可以分治,将 ana^n 变成 afracn2×afracn2a^{frac{n}{2}}\times a^{frac{n}{2}},但如果此时 nn 是奇数,则多乘一个 aa

    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    ll a,b,p=1e9+7;
    ll qpow(ll a,ll b,ll p){
    	ll res=1,tmp=a;
    	while(b){
    		if(b&1)res=(res%p*tmp%p)%p;
    		tmp=(tmp*tmp)%p;
    		b>>=1;
    	}
    	return res;
    }
    int main(){
    	cin>>a>>b>>p;
    	cout<<qpow(a,b,p)<<endl;
    	return 0;
    }
    
    • 5
      @ 2021-9-14 20:46:51

      知识点:快速幂

      递归公式(分治思想):

      $x^y=(x^{\lfloor\frac{y}{2}\rfloor})^2\cdot x^{y-2\cdot{\lfloor\frac{y}{2}\rfloor}}$,而终止条件为 y=0y=0,此时 xy=1x^y=1

      即:

      $x^y=\begin{cases} (x^{\frac{y}{2}})^2\qquad(2\mid y)\\ (x^{\frac{y-1}{2}})^2\cdot x(2\nmid y)\\ 1\qquad\qquad(y=0) \end{cases}$

      代码如下:

      int qpow(int a,int b){//即a^b
          if(b==0) return 1;//终止条件
          else if(b%2==0){
              int k=qpow(a,b/2);
              return k*k%MOD;
          }
          else{
              int k=qpow(a,b/2);
              return k*k%MOD*a%MOD;
          }
          //分治思想
      }
      

      我曾经写过一个及其精彩的错误代码:

      int qpow(int a,int b){//即a^b
          if(b==0) return 1;//终止条件
          else if(b%2==0){
              return qpow(a,b/2)*qpow(a,b/2)%MOD;
          }
          else{
              return qpow(a,b/2)*qpow(a,b/2)%MOD*a%MOD;
          }
          //分治思想
      }
      

      本代码有什么问题?(设问的修辞手法

      答:这里。

      return qpow(a,b/2)*qpow(a,b/2)%MOD;
      

      以及:

      return qpow(a,b/2)*qpow(a,b/2)%MOD*a%MOD;
      

      这里相当于计算了两次qpow(a,b/2)

      所以需要乘 bbaa

      那么此“快速”幂的复杂度为 O(b)O(b)

      真正的快速幂的复杂度约为 O(logb)O(\log{b})

      用上面的那个即可通关。

      • 3
        @ 2022-7-21 21:19:08
        #include<iostream>
        using namespace std;
        int main (){
            int a, b, p;
            int ans = 1;
            scanf("%d%d%d", &a, &b, &p);
            while(b){
                if(b & 1)
                    ans = (long long) ans * a % p;
                a = (long long) a * a % p;
                b >>= 1;
            }
            printf("%d", ans % p);
            return 0;
        }
        
        • 3
          @ 2021-11-30 12:48:17

          代码自认为十分好懂

          #include<cstdio>
          using namespace std;
          #define ll long long
          ll cal(ll a, ll b, ll p)
          {
              ll ans = 1 % p;
              for (; b; b >>= 1)//个人码风原因,也可使用while循环额外加b >>= 1
              {
                  if (b & 1)
                      ans = ans * a % p;//及时取模防止爆掉
                  a = a * a % p;//及时取模防止爆掉
              }
              return ans;
          }
          int main()
          {
          	ll a, b, p;
          	scanf("%lld %lld %lld", &a, &b, &p);
          	printf("%lld", cal(a, b, p));
              return 0;
          }
          
          • 3
            @ 2021-10-6 10:36:04

            快速幂 - OI Wiki (oi-wiki.org)

            #include<bits/stdc++.h>
            using namespace std;
              
            int main()
            {
                unsigned long long a,b,mode ;
                cin>>a>>b>>mode;
                int sum=1;
                a =a%mode;
                while(b>0)
            	{
                    if (b%2==1)
            		{
            			sum =(sum*a)%mode;
            		}
                    b /= 2;
                    a = (a * a) % mode;
            
               }
            cout<<sum;
            }
            
            • 3
              @ 2021-10-3 13:16:15

              快速幂的基本原理是简单的:欲计算 aba^b 的值,只需计算 ab/2a^{b/2} 的值即可。

              在数论题当中,时常涉及到乘法的取模运算。这里用到一个原理:

              $$(a\times b)\,\bmod p= [(a\,\bmod p)\times(b\,\bmod p)]\,\bmod p $$
              int solve(int a,int b){
              	if(b==0) return 1;
              	if(b==1) return a%p;
              	if(b%2==0){
              		int tmp = solve(a,b>>1); //必须预存tmp的值,否则程序的效率与普通乘幂无异
              		return (tmp*tmp)%p;
              	}else{
              		int tmp = solve(a,b>>1);
              		return (tmp*tmp*(solve(a,1))%p)%p;
              	}
              }
              
              • 2
                @ 2023-11-11 18:06:10

                板子题,直接放代码:

                #include<bits/stdc++.h>
                #define int long long
                using namespace std;
                int a,b,m;
                int power(int a,int b,int m){
                    long long ans=1;
                    while(b){
                        if(b&1){
                            ans=ans*a%m;
                        }
                        a=a*a%m;
                        b>>=1;
                    }
                    return ans;
                }
                signed main(){
                   cin>>a>>b>>m;
                   cout<<power(a,b,m);
                }
                
                • 2
                  @ 2023-10-5 10:40:34
                  #include<bits/stdc++.h>
                  #define ll long long
                  using namespace std;
                  ll a,b,p=1e9+7;
                  ll qpow(ll a,ll b,ll p){
                  	ll res=1,tmp=a;
                  	while(b){
                  		if(b&1)res=(res%p*tmp%p)%p;
                  		tmp=(tmp*tmp)%p;
                  		b>>=1;
                  	}
                  	return res;
                  }
                  int main(){
                  	cin>>a>>b>>p;
                  	cout<<qpow(a,b,p)<<endl;
                  	return 0;
                  }
                  
                  
                  • 2
                    @ 2023-3-25 17:32:39
                    #include<bits/stdc++.h>
                    #define ll long long
                    using namespace std;
                    ll a,b,p=1e9+7;
                    ll qpow(ll a,ll b,ll p){
                    	ll res=1,tmp=a;
                    	while(b){
                    		if(b&1)res=(res%p*tmp%p)%p;
                    		tmp=(tmp*tmp)%p;
                    		b>>=1;
                    	}
                    	return res;
                    }
                    int main(){
                    	cin>>a>>b>>p;
                    	cout<<qpow(a,b,p)<<endl;
                    	return 0;
                    }
                    
                    
                    • 2
                      @ 2022-10-15 20:49:49

                      题目大意

                      给出 aa, bb, pp。求 abmodpa^b\bmod p

                      做法

                      注意到 b231b\leq 2^{31} ,所以我们最好可以有一个O(logn)\mathit{O(logn)}的算法来求快速幂。那么,分治,它来了。

                      详细介绍

                      接下来,就是思考如何用分治解决这个题目。当我们求 abmodpa^b\bmod p 时,我们可以把原式子分为两个 ab/2modpa^{b/2}\bmod p 的积, 如果 b1(mod2)b\equiv1\pmod{2} ,还得乘上一个 aa 才能等于 abmodpa^b\bmod p 。这样递归下去,我们就能实现分而治之了。

                      代码

                      #include <bits/stdc++.h>
                      #define int long long
                      using namespace std;
                      int x,y,p;
                      int pw(int x,int y,int p){
                      	int re=1;
                      	while(y){
                      		if(y&1) re=re*x%p;//y&1是判y的奇偶性
                      		x=x*x%p;
                      		y>>=1;//等同于y/=2
                      	}
                      	return re;
                      } 
                      signed main(){
                      	cin>>x>>y>>p;
                      	cout<<pw(x,y,p)<<endl;
                      	return 0;
                      }
                      

                      完结,撒花!!!

                      • 2
                        @ 2022-6-19 12:40:23

                        此题解是 JuliaRoadmap 项目的一部分

                        题解里很多人用递归的方法,这里不再阐述。注意到可以对bb 进行二进制拆分,例如对于12=(1100)212=(1100)_2,只需从左到右循环即可

                        题目中限定 b<231b<2^{31},使用以下代码

                        function main()
                            a=parse(Int, readuntil(stdin,' '))
                            b=parse(Int, readuntil(stdin,' '))
                            p=parse(Int, readline())
                            a%=p
                            ans=1
                            for i in 31:-1:0
                                sign=(b>>i)&1 # 位运算技巧
                                if sign==0
                                    ans=ans*ans%p
                                else
                                    ans=(ans*ans%p)*a%p
                                end
                            end
                            print(ans)
                        end
                        main()
                        

                        评测结果492~614ms

                        • 0
                          @ 2022-10-23 11:23:50

                          使用分治思想,每次将指数 nn 减半,再平方。但如果 nn 是技术,则要再乘 aa

                          #include<bits/stdc++.h>
                          using namespace std;
                          typedef long long ll;
                          const int INF=0x3f3f3f3f;
                          inline ll read()
                          {
                          	ll x=0,f=1;char ch=getchar();
                          	while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
                          	while (ch>='0'&&ch<='9'){x=x*10+ch-48;ch=getchar();}
                          	return x*f;
                          }
                          ll quickpow(ll a,ll b,ll m){
                          	if(b==0)  return 1;
                          	ll tmp=quickpow(a,b/2,m)%m;
                          	ll ans=tmp*tmp%m;
                          	if(b&1)  ans=ans*a%m;
                          	return ans; 
                          }
                          int main(){
                          	ll a,b,p;
                          	a=read(),b=read(),p=read();
                          	cout<<quickpow(a,b,p);
                          	return 0;
                          }
                          
                          
                          • 0
                            @ 2022-8-22 20:14:26

                            学完初一数学自然就会了。

                            #include<bits/stdc++.h>
                            #define ll long long
                            using namespace std;
                            long long a,b,s,ans;
                            ll p(ll a,ll k)
                            {
                            	ll res=1; 
                            	while(k)
                            	{
                            		if(k&1) 
                            		{
                            		   res=(ll)res*a%s;
                            		}
                            		k>>=1;
                            		a=(ll)a*a%s; 
                            	}
                            	return res;
                            }
                            int main()
                            {
                            	cin>>a>>b>>s;
                            	cout<<p(a,b)%s;
                            }
                            
                            • 0
                              @ 2022-5-29 15:53:04
                              a=input().split#输入,切片
                              print(str(pow(int(a[0]),int(a[1]),int(a[2]))))#pow函数
                              
                              • -1
                                @ 2025-1-15 15:22:47

                                注释了啊

                                我第一次在这里做的

                                #include <bits/stdc++.h>
                                using namespace std;
                                /*
                                (a+b)%k = (a%k+b%k)%k
                                (a*b)%k = ((a%k)*(b%k))%k 
                                */
                                
                                //快速幂  (a^x)%p
                                // a=1231321313
                                // x=5464646546
                                // p=12313 
                                
                                long long a,x,p;
                                
                                long long f(int k){//a的k次方 %p的结果 
                                	if(k==0) return 1;
                                	if(k==1) return a%p;
                                	long long tmp=f(k/2);
                                	if(k%2==0){
                                		return tmp*tmp%p;
                                	}else{
                                		return (tmp*tmp%p)*a%p;
                                	}
                                }
                                
                                int main(){
                                	cin>>a>>x>>p;
                                    cout<<f(x);
                                    return 0;
                                }
                                
                                • -1
                                  @ 2024-10-24 11:16:59

                                  位运算 code

                                  #include<stdio.h>
                                  using namespace std;
                                  unsigned long long a,b,mod;
                                  unsigned long long pow(unsigned long long a,unsigned long long b){
                                      unsigned long long ret = 1;
                                      while(b){
                                          if(b&1)
                                              ret=(ret*a)%mod;
                                          a=(a*a)%mod;
                                          b>>=1;
                                      }
                                      return ret;
                                  }
                                  int main(){
                                      scanf("%lld%lld%lld",&a,&b,&mod);
                                      printf("%lld",pow(a,b)%mod);
                                  return 0;
                                  }
                                  
                                  • -1
                                    @ 2024-10-23 19:55:33
                                    #include<bits/stdc++.h>
                                    #define int long long
                                    using namespace std;
                                    int a,b,p;
                                    int qp(int a,int b,int p)
                                    {
                                    	int res=1;
                                    	while(b)
                                    	{
                                    		if(b&1)
                                    		{
                                    			res*=a;
                                    			res%=p;
                                    		}
                                    		a*=a;
                                    		a%=p;
                                    		b>>=1;
                                    	}
                                    	return res;
                                    }
                                    signed main()
                                    {
                                    	ios::sync_with_stdio(false);
                                    	cin.tie(0);
                                    	cout.tie(0);
                                    	cin>>a>>b>>p;
                                    	cout<<qp(a,b,p);
                                    	cout.flush();
                                    	return 0;
                                    }
                                    

                                    板子,就不说了,直接背

                                    • -1
                                      @ 2024-8-11 19:54:10

                                      #include<bits/stdc++.h> using namespace std; long long a,b,p=1e9+7; long long qpow(long long a,long long b,long long p) { long long res=1,tmp=a; while(b) { if(b&1)res=(res%ptmp%p)%p; tmp=(tmptmp)%p; b/=2; } return res; } int main() { cin>>a>>b>>p; cout<<qpow(a,b,p)<<endl; return 0; }

                                      • -1
                                        @ 2024-6-26 20:38:46

                                        #include<bits/stdc++.h> #define ll long long using namespace std; ll a,b,p=1e9+7; ll qpow(ll a,ll b,ll p){ ll res=1,tmp=a; while(b){ if(b&1)res=(res%ptmp%p)%p; tmp=(tmptmp)%p; b>>=1; } return res; } int main(){ cin>>a>>b>>p; cout<<qpow(a,b,p)<<endl; return 0; }

                                        • -1
                                          @ 2024-3-13 14:26:57
                                          #include <bits/stdc++.h>
                                          
                                          using namespace std;
                                          #define int __int128
                                          int read()
                                          {
                                              int x{},w{1};char c= getchar();
                                              while(c>'9' || c<'0') {if(c == '-') w=-1;c = getchar();}
                                              while(c<='9' && c>='0') x = (x<<1)+(x<<3)+c-'0',c = getchar();
                                              return w * x;
                                          }
                                          void write(int x)
                                          {
                                              if(x < 0) x = -x,putchar('-');
                                              if(x>9) write(x/10);putchar(x%10+'0');
                                          }
                                          void writeln(int x)
                                          {
                                              write(x);putchar(10);
                                          }
                                          const int N = 5e5+5;
                                          int f[N],d[N];
                                          int siz[N],son[N];
                                          struct EDGE
                                          {
                                              int nxt,to;
                                          }e[N<<1];
                                          int ecnt{},head[N];
                                          void add(int u,int v)
                                          {
                                              e[++ecnt].to = v;
                                              e[ecnt].nxt = head[u];
                                              head[u] = ecnt;
                                          }
                                          void dfs1(int u,int fa)
                                          {
                                              siz[u] = 1,f[u] = fa,d[u] = d[fa]+1;
                                              for(int i{head[u]};i;i = e[i].nxt)
                                              {
                                                  int v = e[i].to;
                                                  if(v == fa) continue;
                                                  dfs1(v,u);
                                                  siz[u] += siz[v];
                                                  if(siz[v] > siz[son[u]]) son[u] = v;
                                              }
                                          }
                                          int t[N],dfn[N],a[N],o[N],cnt{};
                                          void dfs2(int u,int top)
                                          {
                                              dfn[u] = ++cnt;
                                              a[dfn[u]]=o[u];
                                              t[u] = top;
                                              if(!son[u]) return;
                                              dfs2(son[u],top);
                                              for(int i{head[u]};i;i = e[i].nxt)
                                              {
                                                  int v = e[i].to;
                                                  if(v == f[u] || v == son[u]) continue;
                                                  dfs2(v,v);
                                              }
                                          }
                                          int lca(int u,int v)
                                          {
                                              while(t[u] != t[v])
                                              {
                                                  if(d[t[u]] < d[t[v]]) u^=v^=u^=v;
                                                  u = f[t[u]];
                                              }
                                              return d[u]<d[v] ? u : v;
                                          }
                                          int qp(int a,int b,int p)
                                          {
                                              int res{1};
                                              while(b)
                                              {
                                                  if(b & 1) res = res * a % p;
                                                  a = a * a % p;
                                                  b >>= 1;
                                              }
                                              return res;
                                          }
                                          signed main()
                                          {
                                              int a = read(),b = read(),p = read();
                                              writeln(qp(a,b,p));
                                          }
                                          

                                          信息

                                          ID
                                          171
                                          时间
                                          1000ms
                                          内存
                                          256MiB
                                          难度
                                          2
                                          标签
                                          递交数
                                          1260
                                          已通过
                                          397
                                          上传者