SP7035 The Embarrassed Cryptographer
Luogu 链接
SPOJ 链接
Virtual Judge 链接
题意
题目描述
现已知两个正整数 \(n\) 和 \(k\)(\(4\le n\le10^{100},2\le k\le10^6\)),满足 \(n=p_1p_2\),其中 \(p_1\) 和 \(p_2\) 都是质数,并且 \(p_1\le p_2\)。
若 \(p_1<k\),则输出 \(\texttt{BAD}\) 和 \(p_1\);否则输出 \(\texttt{GOOD}\)。
输入格式
多测。
每行两个正整数 \(n\) 和 \(k\)(\(4\le n\le10^{100},2\le k\le10^6\)),含义见题目描述。
当读到0 0时代表输入结束。
输出格式
见题目描述。
思路
注意到 \(k\le10^6\),因此我们只需先用线性筛筛出 \(10^6\) 范围内的质数,然后对于所有质数 \(p<k\) 都计算 \(n\bmod p\)。
若存在质数 \(p\) 使得 \(n\bmod p=0\),则输出 \(\texttt{BAD}\) 和 \(p\);否则输出 \(\texttt{GOOD}\)。
在实现时,采用压位高精的做法,防止取模过多导致的 TLE。
程序
#include<cstdlib>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<queue>
#include<cstdio>
#include<iostream>
#include<vector>
#include<map>
#include<cmath>
#include<iomanip>
#include<string>
#include<stack>
#define ll long long
#define ull unsigned long long
#define uint unsigned int
#define vl __int128
#define ld long double
#define INF 0x3f3f3f3f
#define ls rt<<1
#define rs rt<<1|1
#define lb(x) ((x)&(-(x)))
#define pb push_back
#define forUp(i,a,b) for(int i=(a);i<=(b);++i)
#define forDown(i,a,b) for(int i=(a);i>=(b);--i)
using namespace std;
const int N=1e6+10,M=100+10;
//#define use_file
//#define more_test
#define need_init
#ifdef more_test
int T;
#endif
//线性筛
int cnt,P[N];bool np[N];
void init(int n=N-10){
cnt=0;
np[0]=np[1]=true;
forUp(x_,2,n){
if(!np[x_])P[++cnt]=x_;
forUp(i,1,cnt){
int x=P[i]*x_;
if(x>n)break;
np[x]=true;
if(x_%P[i]==0)break;
}
}
}
char str[M];int k;
int tlen,len;ll n[20],ans;const ll tmp=10000000000ll;bool flag;
void SOLVE(/*int TestID*/){
while(scanf("%s%d",str+1,&k),k){
memset(n,0,sizeof(n));
flag=true;
//压位
for(tlen=strlen(str+1),len=0;tlen>=9;tlen-=10){
++len;
forUp(i,tlen-9,tlen)n[len]=(n[len]<<1)+(n[len]<<3)+(str[i]^48);
}
if(tlen!=0){
++len;
forUp(i,1,tlen)n[len]=(n[len]<<1)+(n[len]<<3)+(str[i]^48);
}
//计算
forUp(i,1,cnt){
if(P[i]>=k)break;
ans=0;
forDown(j,len,1)ans=(ans*tmp+n[j])%P[i];
if(ans==0){
printf("BAD %d\n",P[i]);
flag=false;
break;
}
}
if(flag)printf("GOOD\n");
}
}
/*
Input:
Output:
*/
int main(){
#ifdef use_file
freopen("test.in","r",stdin);
freopen("test.out","w",stdout);
#endif
#ifdef need_init
init();
#endif
#ifdef more_test
scanf("%d",&T);
for(int i=1;i<=T;++i)SOLVE(/*i*/);
#else
SOLVE();
#endif
return 0;
}

浙公网安备 33010602011771号