分析:怎么看都是超时,但是可以先筛一遍1e6以内的每个数的最小素数
算出每个数由多少个素数组成,然后应用,c[1e6][20]
就是题解的那一套,参照题解,比赛的时候没有想到好的办法筛一个数的因子,醉了
然后赛后发现,预处理因子肯定超时,虽然是O(nlogn)的,但是n是1e6啊,常数太大
而且单组操作只有5e4,所以暴力sqrt(x)即可
#include <iostream> #include <vector> #include <queue> #include <cstdio> #include <cmath> #include <cstring> #include <algorithm> using namespace std; const int N = 1e6+1; int c[N][21],tot,prime[80000],mn[N],cnt[N],q,kase; bool check[N]; char op[5]; void getprime() { for(int i=2; i<=N-1; ++i) { if(!check[i])mn[i]=prime[++tot]=i; for(int j=1; j<=tot; ++j) { if(i*prime[j]>N-1)break; check[i*prime[j]]=true; mn[i*prime[j]]=prime[j]; if(i%prime[j]==0)break; } } } void getcnt() { for(int i=2; i<=N-1; ++i) { int tmp=i; while(tmp!=1)++cnt[i],tmp/=mn[tmp]; } } int main() { getprime(); getcnt(); memset(mn,0,sizeof(mn)); while(~scanf("%d",&q),q) { printf("Case #%d:\n",++kase); memset(c,0,sizeof(c)); int ttt=0; for(int i=0; i<q; ++i) { int x; scanf("%s%d",op,&x); if(op[0]==‘I‘) { if(mn[x]==kase)continue; mn[x]=kase;++ttt; for(int j=1; j*j<=x; ++j) { if(x%j)continue; ++c[j][cnt[x/j]]; if(x/j!=j)++c[x/j][cnt[j]]; } } else if(op[0]==‘D‘) { if(mn[x]!=kase)continue; mn[x]=0;--ttt; for(int j=1; j*j<=x; ++j) { if(x%j)continue; --c[j][cnt[x/j]]; if(x/j!=j)--c[x/j][cnt[j]]; } } else { if(ttt==0){printf("-1\n");continue;} int ans=100; for(int j=1; j*j<=x; ++j) { if(x%j)continue; for(int k=0; k<=20; ++k) { if(c[j][k]) { ans=min(ans,k+cnt[x/j]); break; } } if(x/j!=j) { for(int k=0; k<=20; ++k) { if(c[x/j][k]) { ans=min(ans,k+cnt[j]); break; } } } } if(ans==100)ans=-1; printf("%d\n",ans); } } } return 0; }
时间: 2024-12-05 23:04:30