zoukankan      html  css  js  c++  java
  • 二次剩余小记

    ( ext{yyb}) 的博客看到的,发现似乎并没有想象中的那么难,就学了一下,过了板题,这里记录一下,暂时还是只会二次剩余, (n) 次剩余暂时先放一下。

    模数为奇素数

    下文的 (p) 即是模数。

    我们称 (n) 为模 (p) 意义下的二次剩余当且仅当存在 (x) 使得 (x^2equiv npmod p,xin mathbb{N}) 。下文的 (mathbb{N}) 其实是自然数集。

    • 引理1

    ((A+B)^pequiv A^p+B^ppmod{p})

    • 证明

    显然只需要说明 (dbinom{p}{i}equiv0pmod p,s.t. 1le ile p-1),然后我们发现如果 (p) 是个奇素数的话,那么分子里面的 (p) 就没有办法消去,于是就得证了。

    • 引理2

    (n^{frac{p-1}{2}}equiv 1pmod p)

    (n) 是模 (p) 意义下的二次剩余的充要条件。

    • 证明

    必要性 :设 (x^2equiv npmod p),那么有 (x^{p-1}equiv 1pmod p) ,证毕。

    充分性 :显然。


    接下来,我们考虑随机出一个 (a) 使得 (a^2-n) 不是一个二次剩余,这样的期望尝试次数大概为 (2),再设 (i^2=a^2-n) ,这里的 (i) 显然就不属于 (mathbb{N}) ,我们把它视作虚数之类的东西就好了。然后我们发现就有个性质:

    • 性质

    [i^{p-1}equiv -1pmod p ]

    证明 :首先我们知道 ((i^2)^{frac{p-1}{2}}equiv (a^2-n)^{frac{p-1}{2}} otequiv 1pmod p) (因为 (a^2-n) 不是一个二次剩余),然后又有 ((i^2)^{p-1}equiv 1pmod p),所以 (i^{p-1}equiv -1pmod p)


    我们可(bu)以(neng)发现:

    [(a+i)^{p+1}equiv (a+i)^p(a+i)equiv(a^p+i^p)(a+i)equiv (a-i)(a+i) ]

    [equiv a^2-i^2equiv npmod p ]

    就是说 ((a+i)^{p+1}equiv npmod p),所以说 (sqrt nequiv (a+i)^{frac{p+1}{2}}pmod p)

    可能有人有疑问,((a+i)^{frac{p+1}{2}}) 有没有可能不是一个整数,显然如果你保证有解的话它显然就是一个整数。

    ( exttt{Code})

    #include <bits/stdc++.h>
    using namespace std;
    
    #define Int register int
    #define int long long
    
    template <typename T> inline void read (T &t){t = 0;char c = getchar();int f = 1;while (c < '0' || c > '9'){if (c == '-') f = -f;c = getchar();}while (c >= '0' && c <= '9'){t = (t << 3) + (t << 1) + c - '0';c = getchar();} t *= f;}
    template <typename T,typename ... Args> inline void read (T &t,Args&... args){read (t);read (args...);}
    template <typename T> inline void write (T x){if (x < 0){x = -x;putchar ('-');}if (x > 9) write (x / 10);putchar (x % 10 + '0');}
    
    int p,sqri;
    
    int qkpow (int a,int b){
    	int res = 1;for (;b;b >>= 1,a = 1ll * a * a % p) if (b & 1) res = 1ll * res * a % p;
    	return res;
    }
    int mul (int a,int b){return 1ll * a * b % p;}
    int dec (int a,int b){return a >= b ? a - b : a + p - b;}
    int add (int a,int b){return a + b >= p ? a + b - p : a + b;}
    
    struct node{
    	int real,imag;
    	node (int _real,int _imag) : real (_real) , imag (_imag) {}
    	node operator * (node b){return node (add (1ll * real * b.real % p,1ll * imag * b.imag % p * sqri % p),add (1ll * real * b.imag % p,1ll * b.real * imag % p));}
    	node operator + (node b){return node (add (real,b.real),add (imag,b.imag));}
    	node operator ^ (int b){node a = *this,res = node (1,0);for (;b;b >>= 1,a = a * a) if (b & 1) res = res * a;return res;}
    };
    
    bool check_if_qs (int n){//判断是否是一个二次剩余 
    	return qkpow (n,(p - 1) >> 1) == 1;
    }
    
    bool tryit (int n){
    	if (n == 0){
    		puts ("0");
    		return 1;
    	}
    	int a = rand ();sqri = dec (mul (a,a),n);
    	if (!a || !check_if_qs (sqri)){
    		int x0 = (node (a,1) ^ (p + 1 >> 1)).real;
    		int x1 = p - x0;if (x0 > x1) swap (x0,x1);
    		write (x0),putchar (' '),write (x1),putchar ('
    ');
    		return 1;
    	}
    	else return 0;
    } 
    
    signed main(){
    	int T;read (T);
    	while (T --> 0){
    		int n;read (n,p);
    		if (!check_if_qs (n) && n) puts ("Hola!");
    		else while (1) if (tryit (n)) break;
    	}
    	return 0;
    }
    
  • 相关阅读:
    JDBC原理及常见错误分析
    response,session,cookie
    Activity LifeCycle (安卓应用的运行机制)
    简单的接口取数据渲染到图表
    图表里面双重下拉框进行判断
    用js方式取得接口里面json数据的key和value值
    一个div多个图表共用一个图例
    一个页面多图表展示(四个div的方式)
    vue组件之子组件和父组件
    根据判断对颜色进行改变
  • 原文地址:https://www.cnblogs.com/Dark-Romance/p/13544309.html
Copyright © 2011-2022 走看看