• BZOJ 4522: [Cqoi2016]密钥破解 exgcd+Pollard-Rho


    挺简单的,正好能再复习一遍 $exgcd$~

    按照题意一遍一遍模拟即可,注意一下 $pollard-rho$ 中的细节. 

    #include <ctime> 
    #include <cmath>  
    #include <cstdio>
    #include <algorithm>  
    #define ll long long 
    #define ull unsigned long long 
    #define setIO(s) freopen(s".in","r",stdin), freopen(s".out","w",stdout) 
    using namespace std;           
    ll N,E,C,D,n,P,Q,R;       
    int array[20]={2,11,13,17,19};   
    ll exgcd(ll a,ll b,ll &x,ll &y) 
    {
    	if(!b) 
    	{
    		x=1,y=0; 
    		return a; 
    	}
    	ll ans=exgcd(b,a%b,x,y),tmp=x;     
    	x=y,y=tmp-a/b*y;      
    	return ans;   
    } 
    ll mult(ll x,ll y,ll mod) 
    {
    	ll tmp=(long double)x/mod*y;     
    	return ((ull)x*y-tmp*mod+mod)%mod; 
    } 
    ll qpow(ll base,ll k,ll mod) 
    {
    	ll tmp=1; 
    	for(;k;k>>=1,base=mult(base,base,mod)) if(k&1) tmp=mult(tmp,base,mod); 
    	return tmp; 
    }      
    int isprime(ll x) 
    { 
    	if(x<=1) return 1;   
    	int i,j,k; 
    	ll pre,cur,a;     
    	for(cur=x-1,k=0;cur%2==0;cur>>=1) ++k;        
    	for(i=0;i<5;++i) 
    	{
    		if(x==array[i]) return 1;    
    		a=pre=qpow(array[i],cur,x);           
    		for(j=1;j<=k;++j) 
    		{
    			a=mult(pre,pre,x); 
    			if(a==1&&pre!=1&&pre!=x-1) return 0; 
    			pre=a; 
    		} 
    		if(a!=1) return 0; 
    	} 
    	return 1;   
    }
    ll F(ll x,ll c,ll mod) 
    {
    	return (mult(x,x,mod)+c)%mod;  
    }
    ll pollard_rho(ll x) 
    { 
    	int step,k; 
    	ll s=0,t=0,c=rand()%(x-1)+1,val=1,d;  
    	for(k=1;;k<<=1,s=t,val=1) 
    	{
    		for(step=1;step<=k;++step) 
    		{
    			t=F(t,c,x); 
    			val=mult(val,abs(t-s),x);      
    			if(step%127==0) 
    			{
    				d=__gcd(val,x); 
    				if(d>1) return d; 
    			}
    		} 
    		d=__gcd(val,x); 
    		if(d>1) return d; 
    	}
    } 
    void solve_d() 
    { 
    	for(P=N;P>=N;) 
    		P=pollard_rho(N); 
    	Q=N/P;    
    	R=(P-1)*(Q-1);   
    	ll x,y,gcd; 
    	gcd=exgcd(E,R,x,y);
    	x=(x+R)%R;       
    	D=x;    
    
    }
    int main() 
    { 
    	int i,j; 
    	// setIO("input");      
    	srand((unsigned)time(NULL));
    	scanf("%lld%lld%lld",&E,&N,&C);   
    	for(P=N;P>=N;) 
    		P=pollard_rho(N); 
    	Q=N/P;    
    	R=(P-1)*(Q-1);   
    	ll x,y,gcd; 
    	gcd=exgcd(E,R,x,y);
    	x=(x+R)%R;       
    	D=x;    
    	n=qpow(C,D,N);   
    	printf("%lld %lld
    ",D,n);     
    	return 0; 
    }
    

      

  • 相关阅读:
    UVM系统验证基础知识0(Questasim搭建第一个UVM环境)
    DDR3详解(以Micron MT41J128M8 1Gb DDR3 SDRAM为例)
    正则表达式的基本用法
    Veloce2 Emulator
    Perl入门
    哪一种验证方法最好?形式验证、硬件加速还是动态仿真?
    什么是形式验证?
    穆里尼奥之皮洛斯式胜利
    穆帅:孟菲斯是计划中重要的一部分
    CentOS Netstat命令
  • 原文地址:https://www.cnblogs.com/guangheli/p/11507821.html
Copyright © 2020-2023  润新知