hdu 3589 Jacobi symbol (二次剩余勒让德符号)

本文介绍了一种利用勒让德符号和二次剩余原理解决特定数学问题的方法。通过分解质因数并运用快速幂算法,实现了一个求解J(a,n)的高效算法。代码示例使用C++实现,包括了质数筛、快速幂和勒让德符号的计算。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目链接

题意:交代一下勒让德符号与二次剩余,然后告诉你J(a,n)与L的关系,给定a,n,求J(a,n)。

二次剩余的原理我并没有搞太懂= =,想着毕竟不常见,会用板子就好了。在知道如何求勒让德符号的情况下,只需要将n分解质因数,假设n=p1^k1 * p2^k2 * ... *pm^km,则答案为J(a,p1)^k1 * J(a,p2)^k2 * ... * J(a,pm)^km = L(a,p1)^k1 * L(a,p2)^k2 * ... * L(a,pm)^km。

代码如下:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define For(i,a,b) for(int i=a;i<=b;i++)
#define p_b push_back
#define N 1005
int quick_mod(int a,int b,int c) { int ans = 1; while (b) { if (b&1)ans=(ans*1ll*a)%c; b/= 2; a=(a*1ll*a)%c;} return ans; }
bool notprime[N];
int prime[200],cnt;
void init(){
	notprime[1]=1;
	For(i,2,N-1){
		if(!notprime[i]){
			prime[cnt++]=i;
		}
		for(int j=0;j<cnt&&i*prime[j]<N;j++){
			notprime[i*prime[j]]=1;
			if(i%prime[j]==0){
				break;
			}
		}
	}
}
vector<int> fac;
int Legender(int a,int p)//求勒让德符号
{
	int ans=(quick_mod(a, (p - 1) / 2, p)%p+p)%p;
	if(ans==p-1) return -1;
	else return ans;
}
int solve(int n,int p){
	fac.clear();
	int x=p;
	for(int i=0;i<cnt&&prime[i]<=x;i++){
		while(x%prime[i]==0) x/=prime[i],fac.p_b(prime[i]);
	}
	if(x>1)fac.p_b(x);
	int tmp=1;
	for(int i=0;i<(int)fac.size();i++){
		tmp*=Legender(n,fac[i]);
	}
	return tmp;
}
int main()
{
	init();
	int n,p;
	while (scanf("%d%d",&n,&p)!=EOF)
	{
		printf("%d\n",solve(n,p));
	}
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值