zoukankan      html  css  js  c++  java
  • A. A simple Problem(2019武大校赛现场赛)(吉比特杯第二届湖北省程序设计大赛) 解题报告 Apare_xzc

    A. A simple Problem(2019武大校赛现场赛)(吉比特杯第二届湖北省程序设计大赛) 解题报告

    xzc 2019/4/15


    题意:

    求下列式子,其中有K个b

    ((((a)^b)^b)^b...)^b  % p
    

    数据范围:
      1<=a,b,p<=1E7
      1<=k<=1E18


    输入:
      第一行一个T,代表T组数据
      下面有T行,每行4个数,a,b,k,p


    输出:
    T行,每行一个整数


    样例输入:

    3
    2 3 1 10000
    3 2 2 80
    342 234 567 89
    

    样例输出:

    8
    1
    2
    

    思路:

    拓展欧拉定理:
    
    a^b%p = a^(b%phi[p]+phi[p]) % p   ( b>phi[p] )
    
    a^b%p = a^(b%phi[p]) % p   ( b<=phi[p] )
    
    
    • Phi[p]的衰减速度很快,不到100次就会变为1,然后任意数%1=0
    • 所以我们递归求解即可
    • 判断k个b的幂是否>p可以在求快速幂时,顺便处理出来
    • 具体见代码

    我的代码:

    /*
    Author: xzc
    time: 723ms
    status:AC
    A. A simple problem 
    */
    #include<bits/stdc++.h>
    #define For(i,a,b) for(register int i=(a);i<=(b);++i)
    #define Rep(i,a,b) for(register int i=(a);i>=(b);--i)
    #define Mst(a,b) memset(a,(b),sizeof(a))
    #define LL long long
    using namespace std;
    const int maxn  =1e7+100;
    int sushu[maxn/10];
    bool notPrime[maxn];
    int phi[maxn];
    void getPhiTable(int * p); 
    LL fast_pow(bool & ok,LL a,LL b,LL m)  
    {   //快速幂,oK用于返回a^b是否大于m 
    	ok = false;
    	LL ans = 1;
    	while(b)
    	{
    		if(b&1)
    		{
    			ans = ans*a;
    			if(ans>m) ok = true;
    			if(ans>=m) ans %= m;	
    		} 
    		a = a*a;
    		if(a>m) ok = true;
    		if(a>=m) a%=m;
    		b>>=1; 
    	}
    	return ans;
    }
    LL f(bool & big,LL b,LL k,LL p,bool &flag) //求 (((b^b)^b)...) % p
    {   //flag用于记录之前小于K个b的幂是否大于p 
    	//printf("进入了第%lld层,要计算%lld个%lld %% %lld
    ",k,k,b,p); 
    	if(k==1)
    	{
    		if(b>p) b = b%p+p,flag = true;
    		else b = b%p;
    		return b;
    	}
    	if(p==1) return 1;
    	bool ok = false;
    	LL y = f(ok,b,k-1,phi[p],flag);
    	if(ok||flag) y += phi[p],flag = true; 
    	//printf("回到了第%lld层,要计算pow(%lld,%lld,%lld)
    ",k,b,y,p); 
    	return fast_pow(big,b,y,p); 
    }
    /*
    4
    87 2 77 83
    29 2 53 57
    9122259 6 57 57
    50 4 35 9684961
    
    Answer: 
    70 4 39 9211933
    */
    int main()
    {
    	//freopen("02.txt","r",stdin);
    	//freopen("out.txt","w",stdout);
    	getPhiTable(phi);
    	int T;
    	LL a,b,p,k;
    	scanf("%d",&T);
    	while(T--)
    	{
    		scanf("%lld%lld%lld%lld",&a,&b,&k,&p);
    		int pp = phi[p];	
    		bool ok = false;
    		bool flag = false;
    		LL zz = f(ok,b,k,pp,flag);///zzz = (((b^b)^b)...) % pp K个b 
    		if(ok||flag) zz += pp;
    		LL ans = fast_pow(ok,a,zz,p);
    		printf("%lld
    ",ans);
    	}	
    	return 0;
    } 
    void getPhiTable(int *p)
    {
    	int cnt = 0;
    	int n = maxn-50;
    	p[1] = 1;
    	For(i,2,n)
    	{
    		if(!notPrime[i])
    		{
    			sushu[cnt++] = i;
    			p[i] = i-1;		
    		}
    		for(int j=0;j<cnt&&1ll*i*sushu[j]<=n;++j)
    		{
    			notPrime[i*sushu[j]] = true;
    			if(i%sushu[j])
    				p[i*sushu[j]] = p[i]*(sushu[j]-1);
    			else
    			{
    				p[i*sushu[j]] = p[i]*(sushu[j]);
    				break;
    			}
    		}
    	}	
    }
    

  • 相关阅读:
    安装lnmp 时如何修改数据库数据存储地址及默认访问地址
    ubuntu 设置root用户密码并实现root用户登录
    解决ubuntu 远程连接问题
    linux 搭建FTP服务器
    PHP 根据ip获取对应的实际地址
    如何发布自己的composer包
    使用composer安装composer包报Your requirements could not be resolved to an installable set of packages
    laravel 框架配置404等异常页面
    使用Xshell登录linux服务器报WARNING! The remote SSH server rejected X11 forwarding request
    IoTSharp 已支持国产松果时序数据库PinusDB
  • 原文地址:https://www.cnblogs.com/Apare-xzc/p/12243650.html
Copyright © 2011-2022 走看看