洛谷 4296 [AHOI2007]密码箱 题解 发表于 2020-02-10 | 更新于 2020-02-07 | 阅读次数: 25 本文字数: 502 字 | 阅读时长 ≈ 2 分钟 题意简述给定n,输出所有的整数x满足:0<x<n且x2=1(modn)。 n<=2e9. 思路以下所有的=都表示同余(那个三条横线我不会打…) x2=1(modn)x2−1=0(modn)(x−1)(x+1)=0(modn) 枚举一对a,b使得ab=n。(按对枚举因数) 然后枚举x使得:x−1是a的倍数且x+1是b的倍数,或者x−1是b的倍数且x+1是a的倍数。用set去一下重。 时间复杂度是O(n所有小于√n的因数的和,然后乘一个logn)。反正是能过的吧。 代码复制123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869#include <bits/stdc++.h>using namespace std;namespace Flandre_Scarlet{ #define F(i,l,r) for(int i=l;i<=r;++i) #define D(i,r,l) for(int i=r;i>=l;--i) #define Fs(i,l,r,c) for(int i=l;i<=r;c) #define Ds(i,r,l,c) for(int i=r;i>=l;c) #define MEM(x,a) memset(x,a,sizeof(x)) #define FK(x) MEM(x,0) #define Tra(i,u) for(int i=G.Start(u),__v=G.To(i);~i;i=G.Next(i),__v=G.To(i)) #define p_b push_back #define sz(a) ((int)a.size()) #define iter(a,p) (a.begin()+p) void R1(int &x) { x=0;char c=getchar();int f=1; while(c<'0' or c>'9') f=(c=='-')?-1:1,c=getchar(); while(c>='0' and c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar(); x=(f==1)?x:-x; } void Rd(int cnt,...) { va_list args; va_start(args,cnt); F(i,1,cnt) { int* x=va_arg(args,int*);R1(*x); } va_end(args); } int n; void Input() { R1(n); } set<int> ans; void Soviet() { for(int a=1;a*a<=n;++a) if (n%a==0) //枚举a { int b=n/a; //枚举b (b>a) for(int x=1;x<=n;x+=b) if ((x+1)%a==0) ans.insert(x); //case1 (x-1)%b==0 and (x+1)%a==0 for(int x=b-1;x<=n;x+=b) if ((x-1)%a==0) ans.insert(x); //case2 (x-1)%a==0 and (x+1)%b==0 } while(!ans.empty()) { printf("%d\n",*ans.begin()); ans.erase(ans.begin()); } } #define Flan void Flan IsMyWife() { Input(); Soviet(); }}int main(){ Flandre_Scarlet::IsMyWife(); getchar();getchar(); return 0;}