• LibreOJ2045


    Portal

    Description

    给出三个正整数(e,N,c(leq2^{62}))。已知(N)能表示成(pcdot q)的形式,其中(p,q)为质数。计算(r=(p-1)(q-1),edequiv 1 pmod r),求(c^d mod N)

    Solution

    其实主要就是一件事:分解大数(N)。这里要用到一个叫做Pollard's Rho的算法,可以在约(O(n^{frac{1}{4}}))的时间复杂度上求出一个(n)的因数。具体原理是生日悖论,但我不知道为什么这个是悖论...伪代码如下:

    nxt(x)
        return (x*x+step) mod n
    PR(n)
        while true
            step=rand()
            a=b=rand()
            while true
                a=nxt(a),b=nxt(nxt(b))
                if(a==b) break
                g=gcd(abs(a-b),n)
                if(g!=1) return g
    

    由于(nxt(x))是循环的,所以用以(a)的两倍速度前进的(b)进行判断,一旦(a=b)则说明出现环,尝试换一个参数(step)去随机。

    Code

    //「CQOI2016」密钥破解
    #include <bits/stdc++.h>
    typedef long long lint;
    lint n;
    int pr[10]={0,2,3,5,7,11,13,17};
    lint multi(lint a,lint b){lint t=a*b-(lint)((long double)a*b/n+1e-8)*n;if(t<0)return t+n;return t;}
    inline lint abs(lint x) {return x<0?-x:x;}
    inline lint gcd(lint x,lint y) {return y?gcd(y,x%y):x;}
    int step;
    inline lint nxt(lint x) {return (multi(x,x)+step)%n;}
    lint PR(lint n)
    {
        while(true)
        {
            step=rand();
            lint a,b; a=b=rand();
            while(true)
            {
                a=nxt(a),b=nxt(nxt(b));
                if(a==b) break;
                lint g=gcd(abs(a-b),n);
                if(g!=1) return g;
            }
        }
    }
    inline void exgcd(lint a,lint &x,lint b,lint &y)
    {
        if(b==0) {x=1,y=0; return;}
        lint x1,y1; exgcd(b,x1,a%b,y1);
        x=y1,y=x1-a/b*y1;
    }
    lint inv(lint a,lint m)
    {
        lint x,y; exgcd(a,x,m,y);
        while(x<0) x+=m;
        return x;
    }
    lint pow(lint x,lint y)
    {
        lint r=1,t=x;
        for(lint i=y;i;i>>=1,t=multi(t,t)) if(i&1) r=multi(r,t);
        return r;
    }
    int main()
    {
        lint e,c;
        scanf("%lld%lld%lld",&e,&n,&c);
        lint p=0,q=0;
        for(int i=1;i<=7;i++) {if(n%pr[i]==0) p=pr[i],q=n/p; break;}
        if(!p) p=PR(n),q=n/p;
        lint d=inv(e,(p-1)*(q-1));
        printf("%lld %lld
    ",d,pow(c,d));
        return 0;
    }
    
  • 相关阅读:
    Spring Cloud Stream 使用延迟消息实现定时任务(RabbitMQ)
    rocketmq发送消息的三种方式
    windows下RocketMQ安装部署
    idea多设备自动同步配置
    idea复制springboot的maven项目后,修改了maven名称,但maven工具里的maven名称没改变,不生效
    SpringBoot图文教程16—SpringBoot 多模块开发「web」「打包」
    spring-boot-starter-parent的作用
    JDK8 从永久代到元空间
    Spring 生命周期
    mesos Failed to connect to
  • 原文地址:https://www.cnblogs.com/VisJiao/p/LOJ2045.html
Copyright © 2020-2023  润新知