zoukankan      html  css  js  c++  java
  • 【洛谷P4296】密码箱

    题目

    题目链接:https://www.luogu.com.cn/problem/P4296
    在一次偶然的情况下,小可可得到了一个密码箱,听说里面藏着一份古代流传下来的藏宝图,只要能破解密码就能打开箱子,而箱子背面刻着的古代图标,就是对密码的提示。

    经过艰苦的破译,小可可发现,这些图标表示一个数以及这个数与密码的关系。假设这个数是 \(n\),密码为 \(x\),那么可以得到如下表述: 密码 \(x\) 大于等于 \(0\),且小于 \(n\),而 \(x\) 的平方除以 \(n\),得到的余数为 \(1\)。 小可可知道满足上述条件的 \(x\) 可能不止一个,所以一定要把所有满足条件的 \(x\) 计算出来,密码肯定就在其中。计算的过程是很艰苦的,你能否编写一个程序来帮助小可可呢?

    思路

    \(x^2\equiv 1\pmod n\) 等价于 \((x-1)(x+1)\bmod n=0\)
    \(n=ab\)\(x\) 是解当且仅当存在 \(a,b\) 满足 \(a|(x-1)\)\(b|(x+1)\)
    \(a\leq b\),枚举 \(a\),可以计算出 \(b\),对于每一个 \(b\) 的倍数我们都令他为 \(x+1\),那么我们继续枚举 \(b\) 的倍数,只需要判断 \(x-1\) 是不是 \(a\) 的倍数即可。
    时间复杂度 \(O(n)\),当然这是十分轻松的上界。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    
    int n;
    set<int> s;
    
    int main()
    {
    	scanf("%d",&n);
    	if (n==1) return printf("None"),0;
    	for (int i=1;i*i<=n;i++)
    		if (n%i==0)
    		{
    			int k=n/i;
    			for (ll j=k;j-1<=n;j+=k)
    				if ((j-2)%i==0) s.insert(j-1);
    			for (ll j=k;j+1<=n;j+=k)
    				if ((j+2)%i==0) s.insert(j+1);
    		}
    	s.insert(1);
    	for (set<int>::iterator it=s.begin();it!=s.end();it++)
    		printf("%d\n",*it);
    	return 0;
    }
    
  • 相关阅读:
    python基础(5)
    python基础(4)
    python基础(3)
    python基础(2)
    第一个python程序(2)
    第一个python教程(1)
    【jQuery】
    【JavaScript】
    【练习】HTML+CSS
    【练习】Html
  • 原文地址:https://www.cnblogs.com/stoorz/p/13819663.html
Copyright © 2011-2022 走看看