Jzoj1460 无题noname

227 篇文章 3 订阅
105 篇文章 0 订阅

给定一个N,求出所有1到N之间的x,使得x^2=1(mod N)。

将这个式子变形(x-1)(x+1)=0(MOD P) ,那么就可以枚举P的每一对因数(a,b),我们把方程化为ax*by=P*T(T为任意常数)

那么这里ax,by必须满足ax-by=2,这个可以用扩展gcd求解

求出x,y后,我们将所有形如a*(x*(2/gcd)+k*(b/r))的解加入vector并排序输出(注意正负,对这一步不理解的可以看这里:同余方程,这里相当于是解ax=2(mod b)的所有解)

#include<stdio.h>
#include<math.h>
#include<vector>
#include<algorithm>
#define L long long
using namespace std;
vector<L> ans;
L n,sq;
inline L D(L x){ return (x+n)%n; }
L extgcd(L a,L b,L& x,L& y){
	if(b){ 
		L r=extgcd(b,a%b,y,x); 
		y-=x*(a/b); return r; 
	} else { x=1; y=0; return a; }
}
void adj(L a,L b){
	L x,y,r=extgcd(a,b,x,y);
	if(r>2) return;
	x*=2/r; y*=2/r;
	while(abs(x*a)<n) x-=b/r; x+=b/r;
	while(abs(x*a)<n) {
		ans.push_back(x>0?1ll*x*a-1:-x*1ll*a+1);
		x+=b/r;
	}
}
int main(){
	scanf("%d",&n); 
	for(L i=1;1ll*i*i<=n+3;++i) if(n%i==0) adj(i,n/i);
	sort(ans.begin(),ans.end());
	printf("%d\n",ans[0]);
	for(L i=1,z=ans.size();i<z;++i)
		if(ans[i]!=ans[i-1]) printf("%lld\n",ans[i]);
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值