BZOJ_1406_[AHOI2007]密码箱_枚举+数学

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


x^2 mod n = 1

x^2-1 mod n = 0

(x-1)(x+1) = Kn

设Kn=k1n1+k2n2,其中K=k1*k2,n=n1*n2.

于是可以枚举所有n的约数,再枚举他们的倍数。

枚举后半段约数显然比前半段优。

代码:

#include <cstdio>
#include <string.h>
#include <algorithm>
#include <cstdlib>
using namespace std;
int n,ans[10050],cnt;
bool check(int x) {
if(x<1||x>n) return 0;
return 1ll*x*x%n==1;
}
void add(int x) {
int i;
for(i=0;i<=n;i+=x) {
if(check(i+1)) ans[++cnt]=i+1;
if(check(i-1)) ans[++cnt]=i-1;
}
}
int main() {
scanf("%d",&n);
int i;
for(i=1;i*i<=n;i++) {
if(n%i==0) {
add(n/i);
}
}
sort(ans+1,ans+cnt+1);
cnt=unique(ans+1,ans+cnt+1)-ans-1;
for(i=1;i<=cnt;i++) printf("%d\n",ans[i]);
}

最新文章

  1. Android成长日记-ViewPager的使用
  2. 205 Isomorphic Strings
  3. relative 和 absolute
  4. 实例源码--Android底部功能分类Tab使用实例
  5. B. Fox And Two Dots
  6. 使用QEMU调试Linux内核代码
  7. 开源的asp.net工作流程引擎。 http://ccflow.org
  8. mysql basic operation,mysql总结
  9. ios应用接入微信开放平台
  10. locate/slocate命令
  11. win10下VS2015局域网调试配置
  12. winform 自定义分页控件 及DataGridview数据绑定
  13. js计算元素距离顶部的高度及元素是否在可视区判断
  14. 201621123027 Week02-Java基本语法与类库
  15. PAT1002:A+B for Polynomials
  16. UOJ#348. 【WC2018】州区划分
  17. Go基础系列:Go实现工作池的两种方式
  18. day 35 协程与gil概念
  19. echarts 使用问题
  20. Facebook的Fairseq模型详解(Convolutional Sequence to Sequence Learning)

热门文章

  1. 如何选择 IT 技术书籍
  2. python多线程(三)
  3. File类 递归 获取目录下所有文件文件夹
  4. java多线程异步执行
  5. argument to nsmutablearray method addobject cannot be nil 警告
  6. GoogLeNet系列解读
  7. Codeforces Round #266 (Div. 2) C. Number of Ways
  8. C++字符串转数字,数字转字符串
  9. 【转载】5种网络IO模型
  10. 【C语言】统计数字在排序数组中出现的次数