洛谷P4358密钥破解 [CQOI2016] 数论

正解:数论

解题报告:

先,放个传送门QwQ

这题难点可能在理解题意,,,

所以我先放个题意QAQ

大概就是说,给定一个整数N,可以被拆成两个质数的成绩p*q,然后给出了一个数e,求d满足e*d=1(mod r),其中r=(p-1)*(q-1),最后还会给定一个c,求dc%N

umm就是几个板子题的堆砌昂,,,首先pollard_rho找到pq求出r,然后逆元求出d,最后快速幂走一波

然后就做完辣!over!

然后这里注意一下,就我个人的习惯的话我很喜欢快速幂求逆元,,,因为很简单很无脑,,,但是这道题因为不保证互质所以不能用快速幂,只能用exgcd

另,有一个关于卡时限的小发现,首先显然龟速乘是真的很慢嘛,但是我发现,好像用longdouble乘比__int128乘要慢,,,我也布吉岛为什么QAQ反正好像是这样儿的以后打的时候可以注意下QAQ

然后就麻油辣?放个代码QwQ

 

// luogu-judger-enable-o2
#include<bits/stdc++.h>
using namespace std;
#define il inline
#define ll __int128
#define gc getchar()
#define rl register ll
#define rc register char
#define rb register bool
#define rp(i,x,y) for(rl i=x;i<=y;++i)

ll e,n,c,p,q,d,r;
bool cjk=1;

il ll read()
{
    rc ch=gc;rl x=0;rb y=1;
    while(ch!='-' && (ch>'9' || ch<'0'))ch=gc;
    if(ch=='-')ch=gc,y=0;
    while(ch>='0' && ch<='9')x=(x<<1)+(x<<3)+(ch^'0'),ch=gc;
    return y?x:-x;
}
il ll gcd(rl gd,rl gs){return !gs?gd:gcd(gs,gd%gs);}
il ll multi(rl gd,rl gs,rl mod){return 1ll*gd*gs%mod;}//{rl tmp=((long double)gd/mod*gs+1e-8)*mod;return gd*gs-tmp<0?gd*gs-tmp+mod:gd*gs-tmp;}
il ll rrand(){return 1ll*rand()<<15^rand();}
il ll randd(){return 1ll*rrand()<<30^rrand();}
il ll power(rl x,rl y,rl mod){rl ret=1;while(y){if(y&1)ret=ret*x%mod;x=x*x%mod;y>>=1;}return ret;}
il bool miller_rabin(rl x)
{
    if(x==2 || x==3 || x==5)return true;
    if(x%2==0 || x%3==0 || x%5==0)return false;
    rp(i,1,6)
    {
        rl gdgs=rand()%(x-2)+2;if(power(gdgs,x-1,x)!=1)return false;rl poww=x-1;
        while(!(poww&1))
        {
            poww>>=1;
            rl tmp=power(gdgs,poww,x);
            if(multi(tmp,tmp,x)==1 && tmp!=1 && tmp!=x-1)return false;
        }
    }
    return true;
}
il ll pollard_rho(rl x)
{
    if(!(x%2))return 2;if(!(x%3))return 3;
    rl gs=randd()%x,tmp=randd()%x,gd=(multi(gs,gs,x)+tmp)%x,tim=0,timlim=2;
    while(cjk)
    {
        ++tim;gd=(multi(gd,gd,x)+tmp)%x;
        rl gcdd=gcd((gd-gs+x)%x,x);
        if(gd==gs || !tmp)return x;if(gcdd!=1 && gcdd!=x)return gcdd;if(!(tim^timlim))timlim<<=1,gs=gd;
    }
}
void exgcd(ll a,ll b,ll &x,ll &y){if(!b){x=1;y=0;return;}exgcd(b,a%b,y,x);y-=a/b*x;}
il ll inv(rl a,rl b){rl x,y;exgcd(a,b,x,y);return (x%b+b)%b;}
int main()
{
//     freopen("4358.in","r",stdin);freopen("4358.out","w",stdout);
    srand(time(NULL));
    e=read(),n=read(),c=read();
    p=pollard_rho(n);while(!miller_rabin(p))p=pollard_rho(n);q=n/p;r=(p-1)*(q-1);
//    printf("p=%lld r=%lld q=%lld ???=%lld ???=%lld ???=%lld\n",p,r,q,(p-1)*(q-1),p-1,q-1);
    d=inv(e,r);printf("%lld ",d);printf("%lld\n",power(c,d,n));
    return 0;
}
View Code

 

猜你喜欢

转载自www.cnblogs.com/lqsukida/p/10545257.html