bzoj 1406: [AHOI2007]密码箱 二次剩餘

1406: [AHOI2007]密码箱

Time Limit: 5 Sec  Memory Limit: 64 MB
Submit: 701  Solved: 396
[Submit][Status]

Description

在一次偶然的情况下,小可可得到了一个密码箱,听说里面藏着一份古代流传下来的藏宝图,只要能破解密码就能打开箱子,而箱子背面刻着的古代图标,就是对密码的提示。经过艰苦的破译,小可可发现,这些图标表示一个数以及这个数与密码的关系。假设这个数是n,密码为x,那么可以得到如下表述: 密码x大于等于0,且小于n,而x的平方除以n,得到的余数为1。 小可可知道满足上述条件的x可能不止一个,所以一定要把所有满足条件的x计算出来,密码肯定就在其中。计算的过程是很艰苦的,你能否编写一个程序来帮助小可可呢?(题中x,n均为正整数)

Input

输入文件只有一行,且只有一个数字n(1<=n<=2,000,000,000)。

Output

你的程序需要找到所有满足前面所描述条件的x,如果不存在这样的x,你的程序只需输出一行“None”(引号不输出),否则请按照从小到大的顺序输出这些x,每行一个数。

Sample Input

12

Sample Output

1
5
7
11

HINT

 

Source

  題解傳送門:http://www.cnblogs.com/htfy/archive/2012/12/11/2813448.html

  這道題思路比較獨特,運用了平方差公式解二次剩餘。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<ctime>
#include<cmath>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
#include<string>
#include<queue>
using namespace std;
#ifdef WIN32
#define LL "%I64d"
#else
#define LL "%lld"
#endif
#define MAXN 1100
#define MAXV MAXN*2
#define MAXE MAXV*2
#define INF 0x3f3f3f3f
#define INFL 0x3f3f3f3f3f3f3f3fLL
typedef long long qword;
inline int nextInt()
{
char ch;
int x=;
bool flag=false;
do
ch=(char)getchar(),flag=(ch=='-')?true:flag;
while(ch<''||ch>'');
do x=x*+ch-'';
while (ch=(char)getchar(),ch<='' && ch>='');
return x*(flag?-:);
} int n,m;
vector<int> vec;
int main()
{
freopen("input.txt","r",stdin);
//freopen("output.txt","w",stdout);
int i,j,k;
qword x,y,z;
scanf("%d",&n);
//x^2==1 (mod n)
//x^2-1 == k*n
//(x+1)(x-1)==k*n
//n = a*b
//a|(x+1) b|(x-1)
qword a,b;
for (a=;a*a<=n;a++)
{
if (n%a!=)continue;
b=n/a;
for (x=;x<n;x+=b)
if ((x+)%a==)
vec.push_back(x);
for (x=b-;x<n;x+=b)
if ((x-)%a==)
vec.push_back(x);
}
sort(vec.begin(),vec.end());
vector<int>::iterator it1,it2;
// it1=vec.end();
it1=unique(vec.begin(),vec.end());
for (it2=vec.begin();it2!=it1;it2++)
{
printf("%d\n",*it2);
}
return ;
}
上一篇:HDU4893【线段树单点、区间更新】


下一篇:MQTT协议及推送服务(二)