bzoj1406 : [AHOI2007]密码箱(简单数论)

传送门
简单数论暴力题。
题目简述:要求求出所有满足 x 2 ≡ 1 m o d &ThinSpace;&ThinSpace; n x^2\equiv1 \mod n x21modn 0 ≤ x &lt; n 0\le x&lt;n 0x<n x x x


考虑到使用平方差公式变形。
( x − 1 ) ( x + 1 ) ≡ 0 m o d &ThinSpace;&ThinSpace; n (x-1)(x+1)\equiv0 \mod n (x1)(x+1)0modn
( x − 1 ) ( x + 1 ) = k n (x-1)(x+1)=kn (x1)(x+1)=kn
然后就可以枚举 n n n大于 s q r t n sqrt_n sqrtn的约数 d d d来求出可能的 x x x
由上面的式子知道 d ∣ x − 1 d|x-1 dx1或者 d ∣ x + 1 d|x+1 dx+1因此就很好判断了。
代码:

#include<bits/stdc++.h>
#define ri register int
using namespace std;
int n,tot;
vector<int>ans,stk;
int main(){
	scanf("%d",&n);
	for(ri i=1;i*i<=n;++i)if(n%i==0)stk.push_back(n/i);
	for(ri i=stk.size()-1;~i;--i){
		int d=stk[i];
		for(ri j=d;j<=n;j+=d){
			if((j-2)%(n/d)==0)ans.push_back(j-1);
			if((j+2)%(n/d)==0)ans.push_back(j+1);
		}
	}
	sort(ans.begin(),ans.end()),tot=unique(ans.begin(),ans.end())-ans.begin()-1;
	puts("1");
	for(ri i=0;i<tot;++i)cout<<ans[i]<<'\n';
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值