CF1406E Deleting Numbers
阿新 • • 發佈:2020-09-14
CF1406E Deleting Numbers
做法:
列舉所有小於等於n的素數:
分成兩部分:
小於等於sqrt(n)時:
B詢問一個素數,然後A詢問,如果A詢問結果為0,那麼全刪了,如果A詢問結果為1,說明x是這個素數的倍數,按因數分解的素因子逆向列舉這個x。
大於sqrt(n)時:
分塊A操作刪一個塊的素數,超過或者到最後詢問一個A 1看看有沒有刪少了,刪少了就在這個塊裡。
#include<iostream> #include<cstdio> #include<cstdlib> #include<cmath> #include<climits> #include<cstring> #include<cassert> #include<vector> #include<map> #include<queue> #include<iterator> #include<utility> #include<algorithm> //#include<bits/stdc++.h> using namespace std; typedef long long ll; typedef unsigned long long ull; typedef long double ld; typedef pair<int,int> pii; #define mp make_pair #define fi first #define se second #define All(x) (x).begin(),(x).end() #define Y1 "YES" #define N1 "NO" #define ENDL '\n' #define count2(x) __builtin_popcount(x) #define countleadingzero(x) __builtin_clz(x) inline ll read(){//not solve LLONG_MIN LMAX=9,223,372,036,854,775,807 ll s=0,w=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();} while(ch>='0' && ch<='9')s=s*10+ch-'0',ch=getchar(); return s*w; } const int maxquery=1e4;//最大詢問次數 const int PRSIZE=2e5; int isprime[PRSIZE]; vector<int>primelist; //記錄素數 vector<int>primeval[10000]; int n; void init(){ for(int i=2;i<=n;++i){ isprime[i]=true; } for(int i=2;i<=n;++i){ if(isprime[i]){ int sz=primelist.size(); primeval[sz].push_back(i); for(int j=2;j*i<PRSIZE;++j){ if(isprime[j*i]!=false){ isprime[j*i]=false; primeval[sz].push_back(j*i); } } primelist.push_back(i); } } return ; } vector<int>block;//to solve primelist[query]>n int main(){ n=read(); init(); int allcnt=n; unsigned int querynum=0; bool finder=false; int i=1; for(i=1;i<maxquery;){ if(querynum<primelist.size()&&primelist[querynum]<=sqrt(n)){ int thisnum=primelist[querynum]; { printf("B %d\n",thisnum),++i; fflush(stdout); } int deletenumber=read(); allcnt-=deletenumber; cout<<"A "<<thisnum<<'\n'; fflush(stdout); int nowdeletednumber=read(); if(nowdeletednumber!=0){ int number=thisnum; int answer=thisnum; while(1){ int rp=false; for(unsigned int ip=0;ip<primelist.size()&&primelist[ip]*number<=n;++ip){ printf("B %d\n",primelist[ip]*number),++i; fflush(stdout); int response=read(); if(response==1){ number=primelist[ip]*number; answer=max(answer,number); rp=true; break; } if(response==0){ rp=false; } } if(rp==false)break; } if(answer!=0){ { printf("C %d\n",answer),++i; fflush(stdout); } finder=true; break; } } querynum++; } else if(querynum<primelist.size()&&primelist[querynum]<=n){ //break; //choose 20 as block size int thisnum=primelist[querynum]; { printf("B %d\n",thisnum),++i; fflush(stdout); } int deletenumber=read(); allcnt-=1; block.push_back(thisnum); if(block.size()==100||querynum==primelist.size()-1){ { printf("A 1\n"),++i; fflush(stdout); } int queryans=read(); if(queryans>allcnt){ bool checker=false; for(unsigned int iprime=0;iprime<block.size();++iprime){ { printf("B %d\n",block[iprime]),++i; fflush(stdout); } int getnumber=read(); if(getnumber==1){ { printf("C %d\n",block[iprime]),++i; fflush(stdout); } finder=true; break; } } if(checker){ finder=true; break; } break; } block.clear(); } querynum++; } else break; } if(finder==false){ cout<<"C 1\n"; fflush(stdout); } return 0; }