Processing math: 100%
BZOJ3339:Rmq Problem(&&BZOJ3585) 离线+线段树
BZOJ3251:树上三角形 数学+暴力

BZOJ1406:[AHOI2007]密码箱 数学+暴力

shinbokuow posted @ 10 年前 in BZOJ with tags 数学 暴力 , 1253 阅读

思路:

x是一个可行答案,有x2%n=1,即(x1)(x+1)=kn(kZ).

显然我们可以令x1=k1n1,x+1=k2n2,k=k1k2,n=n1n2.(交换一下也是可以的)

那么我们就可以枚举所有的n1,看一看他能够表达出的x+1或是x1是不是一个合法答案.我们用一个哈希表来支持插入.最后输出即可.

 

但是我们发现枚举所有的n1(n的约数)显然是要超时的.因此我们只枚举n1nn1.这样单次枚举的复杂度为n,而且这样的约数非常少,这样就可以通过了.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include<cstdio>
#include<cstring>
#include<cctype>
#include<iostream>
#include<algorithm>
using namespace std;
  
static const int mod=(1e5)+7;
struct HashSet{
    int head[mod],v[200010],next[200010],ind;
    void reset(){ind=0,memset(head,-1,sizeof head);}
    void insert(int x){
        int ins=x%mod;
        for(int j=head[ins];j!=-1;j=next[j])if(v[j]==x)return;
        v[ind]=x,next[ind]=head[ins],head[ins]=ind++;
    }
}S;
  
int n;
void Solve(int x){
    for(int d=x;d<n-1;d+=x)if((long long)d*(d+2)%n==0)S.insert(d+1);
    for(int d=x;d<=n;d+=x)if(d-2>=1&&(long long)d*(d-2)%n==0)S.insert(d-1);
}
int main(){
    scanf("%d",&n);
    if(n==1)puts("NONE");
    else{
        S.reset(),S.insert(1);
        for(int i=1;i*i<=n;++i)if(n%i==0)Solve(max(i,n/i));
        sort(S.v,S.v+S.ind);
        for(int i=0;i<S.ind;++i)printf("%d\n",S.v[i]);
    }
      
    return 0;
}

 


登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter