洛谷——P4296 [AHOI2007]密码箱

P4296 [AHOI2007]密码箱

 密码x大于等于0,且小于n,而x的平方除以n,得到的余数为1。

求这个密码,$1<=n<=2,000,000,000$

暴力枚举,数据有点儿水$O(nlogn)$,显然过不了$n<=10^9$

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>

#define LL long long
using namespace std;

LL n;
bool flg=false;

int main()
{
    scanf("%lld",&n);
    
    for(int i=0;;i++){
        LL x=i*n+1,p=sqrt(x);
        if(p>n) break;
        if(p*p==x){
            flg=true;
            printf("%lld\n",p);
        }
    }
    if(!flg) return puts("None"),0;
    return 0;
} 

正解:

题目要求$x^x\mod n =1$,也就是求$n|(x^2-1^2)$,即$n|(x-1)\times(x+1)$,既然如此,考虑将$n$拆开,就有$n=a\times b$ $a|(x+1),b|(x-1)$或是$b|(x+1),a|(x-1)$

不妨设$a<b$,枚举$a$,同时枚举两种情况,优先队列+$STL$——$map$判重

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<map>
#include<queue>
#include<vector>

#define LL long long
using namespace std;

LL n;
bool flg=false;

priority_queue<LL,vector<LL>,greater<LL> >Q;
map<LL,bool>M;

int main()
{
    scanf("%lld",&n);
    int p=sqrt(n);
    for(int i=1;i<=p;i++){
        if(n%i==0){
            int b=n/i;
            for(int x=1;x<=n;x+=b)//b|x-1
                if((x+1)%i==0&&!M[x]) Q.push(x),M[x]=1;
            for(int x=b-1;x<=n;x+=b)//b|x+1
                if((x-1)%i==0&&!M[x]) Q.push(x),M[x]=1;
        }
    }
    while(!Q.empty()){
        printf("%lld\n",Q.top());
        Q.pop();
    }
    
    return 0;
} 

或是$set$去重

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<map>
#include<queue>
#include<vector>
#include<set>

#define LL long long
using namespace std;

LL n;
bool flg=false;

set<LL>S;

int main()
{
    scanf("%lld",&n);
    int p=sqrt(n);
    for(int i=1;i<=p;i++){
        if(n%i==0){
            int b=n/i;
            for(int x=1;x<=n;x+=b)//b|x-1
                if((x+1)%i==0)
                    S.insert(x);
            for(int x=b-1;x<=n;x+=b)//b|x+1
                if((x-1)%i==0)
                    S.insert(x);
        }
    }
    while(!S.empty()){
        printf("%lld\n",*S.begin());
        S.erase(S.begin());
    }
    
    return 0;
} 

貌似没有$None$的情况,即数据里不存在$n=1$

扫描二维码关注公众号,回复: 3600749 查看本文章

猜你喜欢

转载自www.cnblogs.com/song-/p/9805126.html