解析
打表发现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);#endifn=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
*/