二次剩余Cipolla法

本文深入探讨了二次剩余求解问题,包括勒让德符号、费马小定理的应用,以及如何通过随机化方法找到二次剩余的平方根。此外,还介绍了BSGS算法在解决离散对数问题中的应用,提供了完整的代码实现。

翻着翻着居然翻到了两个退役选手zy和mw的博客,想到自己可能也会像他们一样省选失利……


由于我比较水,目前只会模数是质数的情况,之后会了可能会补。

很多具体的证明我也不会,限于感性认识,所以请看zy的博客:
https://blog.youkuaiyun.com/a_crazy_czy/article/details/51959546


二次剩余要做什么:

给出n,pn,pn,p,p为一质数。

要求xxx,满足x2=n(mod p)x^2=n(mod~p)x2=n(mod p)

判断无解,或者输出所有的解。


以下的口胡均不考虑n=0或p=2的情况。

首先明确一个点:

如果有x2=n(mod p)x^2=n(mod~p)x2=n(mod p),那么也有(p−x)2=n(mod p)(p-x)^2=n(mod~p)(px)2=n(mod p),并且不会有其它的解。

这个可以证明,假设有其它的解yyy

那么x2−y2=0(mod p)x^2-y^2=0(mod~ p)x2y2=0(mod p)
(x+y)(x−y)=0(mod p)(x+y)(x-y)=0(mod~p)(x+y)(xy)=0(mod p),所以有y=±xy=±xy=±x


勒让德符号:
(ap)={1,a为p的二次剩余−1,a为p的二次非剩余0,a≡0(modp)\left(\frac{a}{p}\right)= \begin{cases} 1, & a为p的二次剩余 \\ -1, & a为p的二次非剩余\\ 0, & a\equiv 0\pmod p \end{cases}(pa)=1,1,0,apapa0(modp)

(ap)=a(p−1)/2(mod p)\left(\frac{a}{p}\right)=a^{(p-1)/2}(mod~p)(pa)=a(p1)/2(mod p)
1.
费马小定理有任意np−1=1(mod p)n^{p-1}=1(mod~p)np1=1(mod p)
所以若有x2=n(mod p)x^2=n(mod~p)x2=n(mod p),那么xp−1=n(p−1)/2=1x^{p-1}=n^{(p-1)/2}=1xp1=n(p1)/2=1
这明显是个必要条件,但是充分我不会证。
2.
反过来,如果n(p−1)/2=−1n^{(p-1)/2}=-1n(p1)/2=1,那一定没有解


做法:
随机一个aaa,设w=a2−n(mod p)w=a^2-n(mod~p)w=a2n(mod p),若w没有二次剩余。

那么x1=(a+w)(p+1)/2x1=(a+\sqrt w)^{(p+1)/2}x1=(a+w)(p+1)/2

结论1:
(a+w)p(a+\sqrt w)^{p}(a+w)p
=∑i=0pCpi∗ai∗wp−i=\sum_{i=0}^{p}C_{p}^{i}*a^i*\sqrt w^{p-i}=i=0pCpiaiwpi
=ap+wp=a^p+\sqrt w^p=ap+wp
=a−w=a-\sqrt w=aw

(a+w)p+1(a+\sqrt w)^{p+1}(a+w)p+1
=(a+w)∗(a−w)=(a+\sqrt w) * (a - \sqrt w)=(a+w)(aw)
=a2−w=n=a^2-w=n=a2w=n

那么n1/2=(a+w)(p+1)/2n^{1/2}=(a+\sqrt w)^{(p+1)/2}n1/2=(a+w)(p+1)/2

如何计算:
w\sqrt ww显然是不存在的,那么可以当作iii来做复数乘法。

据说做完之后w\sqrt ww的系数一定是0,我又不会证明了,hhh…

随机a的次数是O(2)的。

例题:
https://www.codechef.com/problems/FN

这个还需要bsgs。

#include<map>
#include<ctime>
#include<cmath>
#include<cstdio>
#include<algorithm>
#define pp printf
#define ll long long
#define fo(i, x, y) for(int i = x; i <= y; i ++)
using namespace std;

int rand(int x, int y) {
	return ((ll) RAND_MAX * rand() + rand()) % (y - x + 1) + x;
}

ll mo;
int Q;

ll ksm(ll x, ll y) {
	ll s = 1;
	for(; y; y /= 2, x = x * x % mo)
		if(y & 1) s = s * x % mo;
	return s;
}

int pd(ll n) {
	if(!n) return 0;
	return ksm(n, (mo - 1) / 2) == 1;
}

ll w;

struct P {
	ll x, y;
	P() {}
	P(ll _x, ll _y) { x = _x, y = _y;}
};

P operator +(P a, P b) {
	return P((a.x + b.x) % mo, (a.y + b.y) % mo);
}
P operator *(P a, P b) {
	return P((a.x * b.x + a.y * b.y % mo * w) % mo, (a.x * b.y + a.y * b.x) % mo);
}

P ksm(P x, ll y) {
	P s = P(1, 0);
	for(; y; y /= 2, x = x * x)
		if(y & 1) s = s * x;
	return s;
}

ll Sqrt(ll n) {
	if(!n) return 0;
	if(mo == 2) return 1;
	if(!pd(n)) return -1;
	while(1) {
		ll a = rand(0, mo - 1);
		w = (a * a % mo - n + mo) % mo;
		if(pd(w)) continue;
		return ksm(P(a, 1), (mo + 1) / 2).x;
	}
}

map<int, int> q[2];

ll bsgs(ll a, ll b, int k) {
	q[0].clear(); q[1].clear();
	int m = ceil(sqrt(mo));
	ll x = b, am = ksm(a, m);
	fo(i, 1, m) {
		x = x * a % mo;
		q[i & 1][x] = i;
	}
	x = 1;
	fo(i, 1, m) {
		x = x * am % mo;
		if(q[k ^ ((i * m) & 1)][x]) return i * m - q[k ^ ((i * m) & 1)][x];
	}
	return -1;
}

ll a, t, n, ni2, ans;

int main() {
	srand(time (0));
	freopen("a.in", "r", stdin);
	for(scanf("%d", &Q); Q; Q --) {
		scanf("%lld %lld", &n, &mo);
		ni2 = ksm(2, mo - 2);
		a = Sqrt(5); t = (1 + a) * ni2 % mo;
		ans = mo;
		n = a * n % mo;
		ll dat = n * n - 4; dat = (dat % mo + mo) % mo;
		ll q = Sqrt(dat);
		if(q != -1) {
			ll T = (n + q) * ni2 % mo;
			ll x = bsgs(t, T, 1);
			if(x != -1) ans = x;
			T = (n - q + mo) * ni2 % mo;
			x = bsgs(t, T, 1);
			if(x != -1) ans = min(ans, x);
		}
		dat = n * n + 4; dat = (dat % mo + mo % mo);
		q = Sqrt(dat);
		if(q != -1) {
			ll T = (n + q) * ni2 % mo;
			ll x = bsgs(t, T, 0);
			if(x != -1) ans = min(ans, x);
			T = (n - q + mo) * ni2 % mo;
			x = bsgs(t, T, 0);
			if(x != -1) ans = min(ans, x);
		}
		pp("%lld\n", ans == mo ? -1 : ans);
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值