洛谷P4296 [AHOI2007]密码箱

题目

链接

分析

一道有点意思的题目...

主要难点在于想到移项,就是把原式转化成平方差的形式,然后把\(n\)拆分成\(a,b\)

这样做了之后我们就发现\(a\)整除\((x-1)\)\(b\)整除\((x+1)\)或者\(a\)整除\((x+1)\)\(b\)整除\((x-1)\)的时候,\(x\)满足题意

枚举\(a\)\(k*b+1,k*b-1\),然后判断这个\(k*b+1(-1)\)是否被\(a\)整除即可

代码

#include<bits/stdc++.h>
using namespace std;
template <typename T>
inline void read(T &x){
	x=0;char ch=getchar();bool f=false;
	while(!isdigit(ch)){if(ch=='-'){f=true;}ch=getchar();}
	while(isdigit(ch)){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
	x=f?-x:x;
	return ;
}
template <typename T>
inline void write(T x){
	if(x<0) putchar('-'),x=-x;
	if(x>9) write(x/10);
	putchar(x%10^48);
	return ;
}
#define ll long long
ll n,now;
set<ll> s;
int main(){
	read(n);
	if(n==1){
		puts("None");
		return 0;
	}
	s.insert(1);
	now=sqrt(n);
	for(ll i=1;i<=now;i++){
		if(n%i==0){
			ll b=n/i;
			for(ll j=b+1;j<=n;j+=b) if((j+1)%i==0) s.insert(j);
			for(ll j=b-1;j<=n;j+=b) if((j-1)%i==0) s.insert(j);
		}
	}
	if(!s.size()) puts("None");
    for(set<ll>::iterator it=s.begin();it!=s.end();it++) write(*it),putchar('\n');
	return 0;
}

posted @ 2020-12-07 20:17  __Anchor  阅读(63)  评论(0编辑  收藏  举报