给定两个数字在模1e9 + 7意义下x + y的和以及x和y的乘积,求x和y
由于x和y的取值范围,我们可以得到x + y的范围为 0 <= x + y < 2 * p,那么对于第一个式子我们可以得到: x + y = b 或者 x + y = p + b的两种情况.
对于第一种情况,将第一个式子代入第二个式子可得
y * (b - y) = k * p + c
移项得,y ^ 2 - b * y + k * p + c = 0
如果y要有整数解,当且仅当 b ^ b - 4 * (k * p + c) 为完全平方数,从而得到如下方程
a ^ 2 = b * b - 4 * (k * p + c)
对两边同时模p可得
a ^ 2 ≡b * b - 4 * c (mod p)
从而转化为一个二次剩余的问题
当时比赛的时候用下面的博客魔改了一下过了,博客里边有简单的证明
https://blog.csdn.net/acdreamers/article/details/10182281
在比赛之后又参考了下边的博客,才真正理解了这个神奇的东西
https://blog.csdn.net/a_crazy_czy/article/details/51959546
在数论中,特别在同余理论里,一个整数 d \bm{d} d对另一个整数 p \bm{p} p 的二次剩余(英语:Quadratic residue)指X的平方 X 2 \bm{X^2} X2 除以 p \bm{p} p得到的余数。
当存在某个 X \bm{X} X, X 2 ≡ d ( m o d p ) \bm{X^2≡d(mod p) } X2≡d(modp) 式子成立时,称 “ d \bm{d} d 是模 p \bm{p} p 的二次剩余 ”
当对任意 X \bm{X} X,上式都不成立时,称 “ d \bm{d} d 是模 p \bm{p} p 的二次非剩余 ”
关于二次剩余的判定,可以用欧拉准则来判断,具体方法如下:
若 p 是奇质数且 p 不能整除 d ,则:
d 是模 p 的二次剩余当且仅当: d p − 1 2 ≡ 1 ( m o d p ) \bm{d^\frac{p-1}{2}≡ 1(mod p)} d2p−1≡1(modp)
d 是模 p 的二次非剩余当且仅当: d p − 1 2 ≡ − 1 ( m o d p ) \bm{d^\frac{p-1}{2}≡ -1(mod p)} d2p−1≡−1(modp)
以勒让德符号表示,即为: d p − 1 2 ≡ ( d p ) m o d p {\displaystyle d^{\frac {p-1}{2}}\equiv\left({\frac {d}{p}}\right){mod {p}}} d2p−1≡(pd)modp
其中勒让德符号的定义如下:
欧拉从充分性和必要性两个方面证明了上述结论,给出的证明如下:
首先,由于 p {\displaystyle p} p是一个奇素数,由费马小定理, d p − 1 ≡ 1 ( m o d p ) {\displaystyle d^{p-1}\equiv 1{\pmod {p}}} dp−1≡1(modp)。但是 p − 1 {\displaystyle} p-1 p−1是一个偶数,
所以有 ( d p − 1 2 − 1 ) ⋅ ( d p − 1 2 + 1 ) ≡ 0 ( m o d p ) {\displaystyle (d^{\frac {p-1}{2}}-1)\cdot (d^{\frac {p-1}{2}}+1)\equiv 0{\pmod {p}}} (d2p−1−1)⋅(d2p−1+1)≡0(modp)
p {\displaystyle}p p是一个素数,所以 d p − 1 2 − 1 {\displaystyle d^{\frac {p-1}{2}}-1} d2p−1−1和 d p − 1 2 + 1 {\displaystyle d^{\frac {p-1}{2}}+1} d2p−1+1中必有一个是 p {\displaystyle }p p 的倍数。因此 d p − 1 2 {\displaystyle d^{\frac {p-1}{2}}} d2p−1模 p {\displaystyle p} p的余数必然是 1 1 1或 − 1 -1 −1。
必要性:
证明若 d {\displaystyle} d d是模 p {\displaystyle} p p的二次剩余,则 d p − 1 2 ≡ 1 ( m o d p ) {\displaystyle d^{\frac {p-1}{2}}\equiv 1{\pmod {p}}} d2p−1≡1(modp)
若 d {\displaystyle } d d是模 p {\displaystyle } p p的二次剩余,则存在 x 2 ≡ d ( m o d p ) {\displaystyle x^{2}\equiv d{\pmod {p}}} x2≡d(modp), p {\displaystyle } p p跟 d , x {\displaystyle d,x} d,x互质。根据费马小定理得:
d p − 1 2 ≡ x p − 1 ≡ 1 ( m o d p ) {\displaystyle d^{\frac {p-1}{2}}\equiv x^{p-1}\equiv 1{\pmod {p}}} d2p−1≡xp−1≡1(modp)
充分性:
证明若 d p − 1 2 ≡ 1 ( m o d p ) {\displaystyle d^{\frac {p-1}{2}}\equiv 1{\pmod {p}}} d2p−1≡1(modp),则 d {\displaystyle } d d是模 p {\displaystyle } p p的二次剩余 p {\displaystyle } p p是一个奇素数,所以关于 p {\displaystyle } p p的原根存在。设 a {\displaystyle } a a是 p {\displaystyle } p p的一个原根,
则存在 1 ≤ j ≤ p − 1 {\displaystyle 1\leq j\leq p-1} 1≤j≤p−1,使得 d = a j d = a j {\displaystyle d=a^{j}} {\displaystyle d=a^{j}} d=ajd=aj。
于是 a j p − 1 2 ≡ 1 ( m o d p ) {\displaystyle a^{j{\frac {p-1}{2}}}\equiv 1{\pmod {p}}} aj2p−1≡1(modp)
a {\displaystyle } a a是 p {\displaystyle }p p的一个原根,因此 a {\displaystyle } a a模 p {\displaystyle } p p的指数是 p − 1 {\displaystyle} p-1 p−1,于是 p − 1 {\displaystyle} p-1 p−1整除 j ( p − 1 ) 2 {\displaystyle {\frac {j(p-1)}{2}}} 2j(p−1)。这说明 j {\displaystyle } j j是一个偶数。令 i = j 2 {\displaystyle i={\frac {j}{2}}} i=2j,就有 ( a i ) 2 = a 2 i = d {\displaystyle (a^{i})^{2}=a^{2i}=d} (ai)2=a2i=d。 d {\displaystyle } d d是模 p {\displaystyle } p p的二次剩余。
问题描述:
对于给定的 d d d 和 p p p 判断 d d d 是否是 p p p 的二次剩余,
如果是,则输出 X 2 ≡ d ( m o d p ) X^2\equiv d{\pmod {p}} X2≡d(modp)的一个解,
其中, p p p 是奇素数。
题目传送门:http://acm.timus.ru/problem.aspx?space=1&num=1132
对于 0 < = X < = p − 1 , X p − 1 2 ≡ 1 ( m o d p ) 0 <= X < = p - 1,X^{\frac{p - 1}{2}}\equiv 1{\pmod {p}} 0<=X<=p−1,X2p−1≡1(modp)有 p − 1 2 {\frac{p - 1}{2}} 2p−1个解
证明如下:
设 u , v u,v u,v是 X X X的两个解,我们可以得到 u 2 − v 2 ≡ 0 ( m o d p ) u^2 - v ^ 2\equiv 0{\pmod{p}} u2−v2≡0(modp)
进一步化简得到 ( u − v ) ∗ ( u + v ) ≡ 0 ( m o d p ) (u - v)*(u + v)\equiv0{\pmod{p}} (u−v)∗(u+v)≡0(modp),由 X X X的范围我们可以指导,
p ∣ ( u + v ) p | (u + v) p∣(u+v),并且 u + v = p u + v = p u+v=p,所以有 p − 1 2 {\frac{p - 1}{2}} 2p−1个解。
为了求出 X X X的解,我们通过随机数找到一个满足 ( a − n 2 p ) (\frac{a - n ^ 2}{p}) (pa−n2)为-1的根据引理我们可以知道这样的 a a a一共有 p − 1 2 \frac{p - 1}{2} 2p−1个,因此求出这样的 a a a的期望次数为 p − 1 2 p \frac{p - 1}{2 p} 2pp−1约为 1 2 \frac{1}{2} 21,基本上我们随机两次就可以得到这样的 a a a,一般我们会随机比较多的次数防止自己脸黑。
在的得到这样的一个 a a a之后我们做如下的处理:
①取 a 2 − n \sqrt{a ^ 2 - n} a2−n为基本的虚数单位,设为 w w w,类比 − 1 \sqrt{-1} −1作为 i i i
②构造一个与当前虚数单位所对应的数域,类比于实数到复数,则在这个数域中所有的数字都可以表示为 a + b w a + bw a+bw的形式
③验证当前数域的运算的封闭性、交换律、结合律、分配律,即验证它是一个合法的数域
对于这个数域,我们可以得到如下的结论:
① w p ≡ − w ( m o d p ) w^p\equiv-w{\pmod{p}} wp≡−w(modp)
证明:根据 ( w 2 p ) (\frac{w ^ 2}{p}) (pw2)为 − 1 -1 −1我们可以知道, w 2 p − 1 2 ≡ − 1 ( m o d p ) {w^2}^{\frac{p-1}{2}}\equiv -1\pmod{p} w22p−1≡−1(modp),从而我们知道 w p = w p − 1 ∗ w , w p ≡ − w ( m o d p ) w^p = w ^{p - 1} * w,w^p\equiv-w\pmod p wp=wp−1∗w,wp≡−w(modp)
② ( a + b ) p ≡ a p + b p ( m o d p ) (a + b) ^ p \equiv a ^ p + b ^ p{\pmod p} (a+b)p≡ap+bp(modp)
证明见我之前写的题解:https://blog.csdn.net/z472421519/article/details/99842319
我们取 X ≡ ( a + w ) p + 1 2 ( m o d p ) X \equiv (a + w) ^{\frac{p + 1}{2}}\pmod p X≡(a+w)2p+1(modp)
我们可以得到 X 2 ≡ ( a + w ) p + 1 ( m o d p ) X ^ 2 \equiv(a + w)^{p + 1} \pmod p X2≡(a+w)p+1(modp) X 2 ≡ ( a + w ) p ∗ ( a + w ) ( m o d p ) X ^ 2 \equiv(a + w)^{p} * (a + w) \pmod p X2≡(a+w)p∗(a+w)(modp)
利用刚才的结论 X 2 ≡ ( a p + w p ) ∗ ( a + w ) ( m o d p ) X ^ 2 \equiv(a^p + w^p) * (a + w) \pmod p X2≡(ap+wp)∗(a+w)(modp) X 2 ≡ ( a p − w ) ∗ ( a + w ) ( m o d p ) X ^ 2 \equiv(a^p-w) * (a + w) \pmod p X2≡(ap−w)∗(a+w)(modp)
再利用费马小定理 a p ≡ a ( m o d p ) a ^ p \equiv a \pmod p ap≡a(modp) 得到,
X 2 ≡ ( a − w ) ∗ ( a + w ) ( m o d p ) X ^ 2 \equiv(a - w) * (a + w) \pmod p X2≡(a−w)∗(a+w)(modp)
X 2 ≡ ( a 2 − w 2 ) ( m o d p ) X ^ 2 \equiv(a^2 - w^2) \pmod p X2≡(a2−w2)(modp)
代入 w = a − n w = \sqrt{a - n} w=a−n
X 2 ≡ n ( m o d p ) X ^ 2 \equiv n \pmod p X2≡n(modp),即 X X X满足之前的二次剩余方程
#include
#include
#include
#include
#include
#include
using namespace std;
typedef long long LL;
LL quick_mod(LL a, LL b, LL m)
{
LL ans = 1;
a %= m;
while(b)
{
if(b & 1)
{
ans = ans * a % m;
b--;
}
b >>= 1;
a = a * a % m;
}
return ans;
}
struct T
{
LL p, d;
};
LL w;
//二次域乘法
T multi_er(T a, T b, LL m)
{
T ans;
ans.p = (a.p * b.p % m + a.d * b.d % m * w % m) % m;
ans.d = (a.p * b.d % m + a.d * b.p % m) % m;
return ans;
}
//二次域上快速幂
T power(T a, LL b, LL m)
{
T ans;
ans.p = 1;
ans.d = 0;
while(b)
{
if(b & 1)
{
ans = multi_er(ans, a, m);
b--;
}
b >>= 1;
a = multi_er(a, a, m);
}
return ans;
}
//求勒让德符号
LL Legendre(LL a, LL p)
{
return quick_mod(a, (p-1)>>1, p);
}
LL mod(LL a, LL m)
{
a %= m;
if(a < 0) a += m;
return a;
}
LL Solve(LL n,LL p)
{
if(p == 2) return 1;
if (Legendre(n, p) + 1 == p)
return -1;
LL a = -1, t;
while(true)
{
a = rand() % p;
t = a * a - n;
w = mod(t, p);
if(Legendre(w, p) + 1 == p) break;
}
T tmp;
tmp.p = a;
tmp.d = 1;
T ans = power(tmp, (p + 1)>>1, p);
return ans.p;
}
int main()
{
LL t;
scanf("%d", &t);
while(t--)
{
LL n,p,N;
LL x,y;
scanf("%lld%lld",&x,&y);
p = 1e9 + 7;
n = x * x - 4 * y;
N = (x + p) * (x + p) - 4 * y;
// //printf("%lld",n);
if(n == 0)
{
printf("%lld %lld\n",x / 2,x / 2);
continue;
}
LL a;
LL X,Y;
bool suc = false;
for(int i = 1;i <= 10;i++)
{
if(n > 0)
{
a = Solve(n, p);
X = (x - a) / 2,Y = (x + a) / 2;
if(((X + Y) % p == (x % p) && (X * Y) % p == y) && (X >= 0 && X <= p) && (Y >= 0 && Y <= p))
{
suc = true;
break;
}
}
if(N > 0)
{
a = Solve(N, p);
X = (x + p - a) / 2,Y = (x + p + a) / 2;
if(((X + Y) % p == (x % p) && (X * Y) % p == y) && (X >= 0 && X <= p) && (Y >= 0 && Y <= p))
{
suc = true;
break;
}
}
}
if(suc)
printf("%lld %lld\n",X,Y);
else
printf("-1 -1\n");
}
return 0;
}
不知道为啥有的时候会出错,考虑到随机算法的脸黑性,我加了个暴力判断,在运算超过十次之后就直接 − 1 , − 1 -1,-1 −1,−1输出