The Embarrassed Cryptographer POJ - 2635 同余模+高精度处理 +线性欧拉筛(每n位一起处理)

题意:给出两数乘积K(1e100) 和 一个数L(1e6)  问有没有小于L(不能等于)的素数是K的因数

思路:把数K切割 用1000进制表示   由同余模公式知   k%x=(a*1000%x+b*1000*1000%x+c*1000*1000*1000%x....)

   a b c等为 相应位置的三位数  这样切割可以减少模的次数 防止超时

 

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<vector>
 4 #include<cmath>
 5 #include<iostream>
 6 using namespace std;
 7 const int maxn=1e6+1000;
 8 int primes[maxn];
 9 int vis[maxn];
10 int cnt;
11 void init(){
12      cnt=0;
13     for(int i=2;i<maxn;i++){
14         if(!vis[i])primes[cnt++]=i;
15         for(int j=0;j<cnt&&i*primes[j]<maxn;j++){
16             vis[i*primes[j]]=1;
17             if(i%primes[j]==0)break;
18         }
19     }
20 }
21 char k[1000];
22 int kt[1000];
23 int l;
24 int lenkt;
25 bool check(int prime){
26     int ans=0;
27     for(int i=lenkt-1;i>=0;i--){
28         ans=(ans*1000+kt[i])%prime;
29     }
30     if(ans==0)return 1;
31     return 0;
32 }
33 int main(){
34     init();
35     while(scanf("%s%d",k,&l)==2&&l&&k[0]!='0'){
36         int len=strlen(k);
37         memset(kt,0,sizeof(kt));
38         for(int i=0;i<len;i++){
39             int temp=(len-i+2)/3-1;//从后往前3个3个数 +2向上取整
40             kt[temp]=kt[temp]*10+k[i]-'0';
41         }
42          lenkt=(len+2)/3;//+2是向上取整
43          int flag=0;
44          for(int i=0;i<cnt&&primes[i]<l;i++){
45              if(check(primes[i])){
46                  printf("BAD %d\n",primes[i]);
47                  flag=1;
48                  break;
49              }
50 
51          }
52          if(!flag){
53              printf("GOOD\n");
54          }
55     }
56     return 0;
57 }

 

posted @ 2019-01-16 21:57  tttttttttrx  阅读(117)  评论(0编辑  收藏  举报