二次剩余学习笔记
注意,下面的运算都是在模意义下进行的。
给定 ,求
存在条件为 ,证明用费马小定理,略。
如何求出 ,随机一个 不存在 二次剩余的值 ,设为
这里可以把 理解为一个虚数。由于 不存在二次剩余,所以
那么
我们要求 ,可以扩域计算。
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
int read()
{
int s=0;
char ch=getchar();
while(ch>'9'||ch<'0')
ch=getchar();
while(ch>='0'&&ch<='9')
s=s*10+ch-48,ch=getchar();
return s;
}
int pown(int x,int y,int p)
{
if(!y)
return 1;
int t=pown(x,y>>1,p);
if(y&1)
return 1LL*t*t%p*x%p;
return 1LL*t*t%p;
}
mt19937 gen(time(0));
int t,n,p,a,k;
struct node{
LL x,y;
node operator*(const node&n)const{
return (node){(x*n.x+y*n.y%p*k)%p,(y*n.x+x*n.y)%p};
}
};
node pown(node x,int y)
{
if(!y)
return (node){1,0};
node t=pown(x,y>>1);
if(y&1)
return t*t*x;
return t*t;
}
int main()
{
t=read();
while(t--)
{
n=read(),p=read();
if(!n)
{
puts("0");
continue;
}
if(pown(n,p-1>>1,p)^1)
puts("Hola!");
else
{
while(1)
{
a=gen()%p,k=(1LL*a*a%p+p-n)%p;
if(pown(k,p-1>>1,p)==1)
continue;
int g=pown((node){a,1},p+1>>1).x;
if(p-g<g)
printf("%d %d\n",p-g,g);
else
printf("%d %d\n",g,p-g);
break;
}
}
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 如何调用 DeepSeek 的自然语言处理 API 接口并集成到在线客服系统
· 【译】Visual Studio 中新的强大生产力特性
· 2025年我用 Compose 写了一个 Todo App