• BZOJ1406:[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

    Solution

    $x^2=k imes n+1$

    $(x+1)(x-1)=k imes n$

    设$n=a imes b (a<b)$

    $a imes b | (x+1)(x-1)$

    $a|(x+1),b|(x-1)$或者$a|(x-1),b|(x+1)$。

    枚举$n$的一个较大的质因数$b$的倍数,就可以将其看做$x-1$或$x+1$,然后代入到$a|(x+1)$或$a|(x-1)$里面验证一下就好了。记得去重。

    $n=1$的时候问题无解(不过好像没有这种数据)

    Code

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<set>
     4 #define LL long long
     5 using namespace std;
     6 
     7 LL n;
     8 set<LL>s;
     9 set<LL>::iterator it;
    10 
    11 int main()
    12 {
    13     scanf("%lld",&n);
    14     if (n>1) s.insert(1);
    15     for (LL i=1; i*i<=n; ++i)
    16     {
    17         if (n%i) continue;
    18         LL x=n/i;
    19         for (LL j=x; j<=n; j+=x)
    20         {
    21             if (!((j-2)%i)) s.insert(j-1);
    22             if (!((j+2)%i)) s.insert(j+1);
    23         }
    24     }
    25     if (s.empty()) {puts("None"); return 0;}
    26     for (it=s.begin(); it!=s.end(); ++it)
    27         if (*it<n) printf("%lld
    ",*it);
    28 }
  • 相关阅读:
    Linux常用命令学习2---(文件搜索命令locate find、命令搜索命令whereis which、字符串搜索命令grep、帮助命令man)
    LeetCode Perfect Squares
    华为笔试 数字转中文拼音
    二位数组 顺时针打印矩阵
    LeetCode Interleaving String
    LeetCode Coins in a Line
    LeetCode Backpack
    LeetCode Unique Paths
    LeetCode Minimum Path Sum
    腾讯模拟笔试题
  • 原文地址:https://www.cnblogs.com/refun/p/10100290.html
Copyright © 2020-2023  润新知