zoukankan      html  css  js  c++  java
  • 二次剩余(模板)

    二次剩余

    存在 (x^2 \% p = n), 如果存在这样的(x)那么,认为(( dfrac{n}{p})) 有解。

    • ((dfrac{n}{p}) = 1): n在模p意义下是二次剩余

    • ((dfrac{n}{p}) = -1):a在模p意义下是非二次剩余

    • ((dfrac{n}{p}) = 0)(n \% p = 0)

    (p)是一个奇素数 , ((dfrac{n}{p}) = n^ {frac{p-1}{2} })

    步骤

    因为有解的情况下, 大约有(dfrac{p-1}{2})(a)满足条件,大约随机数算出的期望是(2), 所以就可以放心的随机数了

    • (a = rand() \% p)
    • (w = a*a - n)
    • ((dfrac{w}{p}) = w^ {frac{p-1}{2} }= -1)(x = (a +sqrt{w})^{frac{p+1}{2}})((dfrac{n}{p}))的解

    因为要计算((a +sqrt{w})^{frac{p+1}{2}}), 可以把((a +sqrt{w})^{frac{p+1}{2}})看成两部分来乘(类似于虚数乘法,把(sqrt{w})看成(i))

    代码

    ll w;
    struct Num{	
        ll x, y;
        Num(){
            x = y = 0;
        }
        Num(ll xx, ll yy){
            x = xx;
            y = yy;
        }
        Num operator * (Num const & a)const{
            Num ans;
            ans.x = ((x * a.x)%p + (y * a.y)%p * w %p + p)%p;
            ans.y = ((x * a.y)%p + (y * a.x)%p + p)%p;
            return ans;
        }
    };
    
    ll pow_num(Num a, ll b){	
        Num ans = {1, 0};
        while(b){
            if(b&1)
                ans = ans*a;
            a = a*a;
            b /= 2;
        }
        return ans.x%p;
    }
    
    ll pow(ll a, ll b){
        ll ans = 1;
        while(b){
            if(b&1)
                ans = ans*a%p;
            a = a*a%p;
            b /= 2;
        }
        return ans;
    }
    
    ll check(ll n){
        ll ans = pow(n, (p-1)/2);
        if(ans == p-1)
            return -1;
        else
            return 1;
    }
    
    ll solve(ll n){
        n %= p;
        if(check(n) == -1)	\如果当前的check(n) == -1那么就不存在解,返回-1
            return -1;
        if(p == 2) return n;	\p = 2的时候, n = 0,1。那么x = n
        ll a;
        srand(time(NULL));
        while(1){
            a = rand()*13331%p;		\随机数一个a
            w = ((a*a%p - n)%p + p)%p;	
            if(check(w) == -1)
                break;
        }
        Num ans = {a, 1};
        return pow_num(ans, (p+1)/2);
    }
    
  • 相关阅读:
    python3图片转化成字符画
    ubuntu 18.04安装PIL(Python Imaging Library )
    Ubuntu 18.04安装钉钉
    django 使用iframe跨域请求
    django 自定义日志字段
    Ubuntu18.04下安装搜狗输入法(亲测有效)
    Nginx 配置指令手册
    js闭包Demo
    自己写了一个无缝滚动的插件(jQuery)
    写JQuery 插件 什么?你还不会写JQuery 插件
  • 原文地址:https://www.cnblogs.com/zhuyou/p/11364593.html
Copyright © 2011-2022 走看看