zoukankan      html  css  js  c++  java
  • 2018 China Collegiate Programming Contest Final (CCPC-Final 2018)-K

    2018 China Collegiate Programming Contest Final (CCPC-Final 2018)-K - Mr. Panda and Kakin-中国剩余定理+同余定理


    【Problem Description】

    [求解x^{2^{30}+3}=cpmod n ]

    其中(n=pcdot q)(p)为小于(x)的最大素数,(q)为大于(x)的最小素数,(x)([10^5,10^9])内随机选择的数。(0< c<n)

    【Solution】

    (a=2^{30}+3),所以有(x^a=cpmod nLeftrightarrow x^{a mod varphi(n)}=cpmod n)。又因为(n=pcdot q),所以有(x^{a mod (p-1)cdot (q-1)}=cpmod n),求出(a)在模((p-1)cdot (q-1))意义下的逆元(d),则(x=c^dpmod n)。然后用中国剩余定理求解答案(x)即可。

    至于(p,q),由题意可知,(p,q)都在(sqrt{n})附近,所以暴力求解即可。


    【Code】

    #include<bits/stdc++.h>
    using namespace std;
    #define int long long
    int exgcd(int a,int b,int &x,int &y){ //扩展欧几里得
    	if(a==0&&b==0) return -1;
    	if(b==0){
    		x=1;y=0;
    		return a;
    	}
    	int gcd=exgcd(b,a%b,y,x);
    	y-=a/b*x;
    	return gcd;
    }
    int solve(int a,int b,int c){ //求逆元
    	int x,y;
    	int gcd=exgcd(a,b,x,y);
    	if(c%gcd!=0) return -1;
    	return (x%b+b)%b;
    }
    int fpow(int a,int b,int mod){ //快速幂
    	int ans=1;a%=mod;
    	while(b){
    		if(b&1) (ans*=a)%=mod;
    		(a*=a)%=mod;
    		b>>=1;
    	}
    	return ans;
    }
    int fmul(int a,int b,int mod){ //快速乘
    	int ans=0;a%=mod;
    	while(b){
    		if(b&1) ans=(ans+a)%mod;
    		a=(a+a)%mod;
    		b>>=1;
    	}
    	return ans;
    }
    int crt(int ai[], int mi[], int len) { //中国剩余定理
        int ans = 0, lcm = 1;
        for (int i = 0; i < len; i++) lcm *= mi[i];
        for (int i = 0; i < len; i++) {
            int Mi = lcm / mi[i];
            int inv = fpow(Mi, mi[i] - 2, mi[i]);
            int x = fmul(fmul(inv, Mi, lcm), ai[i], lcm); //若lcm大于1e9需要用快速乘fmul
            ans = (ans + x) % lcm;
        }
        return ans;
    }
    int mi[5],ai[5];
    signed main(){
    	ios::sync_with_stdio(false);
    	cin.tie(0);
    	int T,ca=0;cin>>T;
    	while(T--){
    		cout<<"Case "<<++ca<<": ";
    		int n,c,p,q;cin>>n>>c;
    		for(int i=sqrt(n);i>=0;i--) if(n%i==0){
    			p=i;q=n/i;
    			break;
    		}
    		int d=solve((1LL<<30)+3,(p-1)*(q-1),1);
    		if(d==-1){
    			cout<<"-1"<<endl;
    			continue;
    		}
    		ai[0]=fpow(c,d,p);ai[1]=fpow(c,d,q);
    		mi[0]=p;mi[1]=q;
    		cout<<crt(ai,mi,2)<<endl;
    	}
    	return 0;
    }
    
    
  • 相关阅读:
    基于雪花算法的单机版
    Spring cloud gateway自定义filter以及负载均衡
    logback转义符与MDC
    录音地址文件保存
    maven加载本地jar
    ES Log4J配置信息
    java线程池
    openstreetmap的数据下载
    php更新版本后(路径更改后)要做的调整
    重启IIS
  • 原文地址:https://www.cnblogs.com/--Simon/p/11725961.html
Copyright © 2011-2022 走看看