解析
打表发现1e5以内的质因子是9592个
就是它没错了
容易想到枚举因子判断答案是否异常来判断是否包含该质因子
但是这个方法在最小质因子处是不奏效的
那么如何找到最小的质因子呢?
考虑把所有的质因子分成m\sqrt mm块
然后每扫完一块,问一下 (A,1)(A,1)(A,1)
如果异常,那么最小质因子就在这块里
暴力扫一遍找出来即可
代码
#include<bits/stdc++.h>
using namespace std;
const int N=3e5+100;
const int mod=1e9+7;
double eps=1e-10;
#define ll long long
ll read(){
ll x=0,f=1;char c=getchar();
while(!isdigit(c)){if(c=='-')f=-1;c=getchar();};
while(isdigit(c)){x=x*10+c-'0';c=getchar();};
return x*f;
}
int n,m;
int vis[N];
ll p[N],tot;
int sum,w;
int ans(1);
bool jd;
int main(){
#ifndef ONLINE_JUDGE
//freopen("a.in","r",stdin);
//freopen("a.out","w",stdout);
#endif
n=read();sum=n;
for(int i=2;i<=n;i++){
if(vis[i]) continue;
vis[i]=1;p[++tot]=i;
for(int j=i+i;j<=n;j+=i) vis[j]=1;
}
printf("tot=%d\n",tot);
w=floor(sqrt(tot));
memset(vis,0,sizeof(vis));
for(int i=1;i<=tot;i++){
//if(ans*p[i]>n) break;
int now(0);
for(int j=p[i];j<=n;j+=p[i]){
if(vis[j]) continue;
vis[j]=1;now++;sum--;
}
printf("B %d\n",p[i]);//fflush(stdout);
int x=read();
if(x!=now){
ans*=p[i];
ll o=p[i]*p[i];
while(o<=n){
printf("A %lld\n",o);//fflush(stdout);
x=read();
if(!x) break;
ans*=p[i];
o*=p[i];
}
}
if(!jd&&(i%w==0||i==tot)){
printf("A 1\n");//fflush(stdout);
x=read();
if(x==sum) continue;
for(int j=(i-1)/w*w+1;j<=i;j++){
printf("A %d\n",p[j]);//fflush(stdout);
x=read();
if(x){
jd=1;
ans*=p[j];
ll o=p[j]*p[j];
while(o<=n){
printf("A %lld\n",o);//fflush(stdout);
x=read();
if(!x) break;
ans*=p[j];
o*=p[j];
}
break;
}
}
}
}
printf("C %d\n",ans);fflush(stdout);
return 0;
}
/*
2 3
7 4 9 9
1 2 8
3 1
4 2 4
*/