CF1406E Deleting Numbers
CF1406E Deleting Numbers
做法:
枚举所有小于等于n的素数:
分成两部分:
小于等于sqrt(n)时:
B询问一个素数,然后A询问,如果A询问结果为0,那么全删了,如果A询问结果为1,说明x是这个素数的倍数,按因数分解的素因子逆向枚举这个x。
大于sqrt(n)时:
分块A操作删一个块的素数,超过或者到最后询问一个A 1看看有没有删少了,删少了就在这个块里。
实现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);
}
checker=true;
break;
}
}
if(checker){
finder=true;
break;
}
}
block.clear();
}
querynum++;
}
else break;
}
if(finder==false){
cout<<"C 1\n";
fflush(stdout);
}
return 0;
}
实现2:
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<climits>
#include<cstring>
#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;
}
constexpr int SIZE=1e5+1;
constexpr int PRSIZE=1e4;//cnt=9592
int primelist[PRSIZE],pcnt=0;
bool isprime[SIZE];
int n;
//vector<int>primeval[PRSIZE];
void init(){
for(int i=2;i<=n;++i) isprime[i]=true;
for(int i=2;i<=n;++i){
if(isprime[i]==true){
primelist[pcnt++]=i;
for(int j=2;j*i<=n;++j)
isprime[i*j]=false;
}
}
}
inline int fpow(int a,int b){
if(b==0) return 1;
if(a==0) return 0;
int ans=1,base=a;
for(;b>0;b/=2){
if(b&1)ans*=base;
base=base*base;
}
return ans;
}
constexpr int BLOCKSIZE=98;//sqrt(9592)
int block[BLOCKSIZE],bcnt;
int main(){
n=read();
int sq=sqrt(double(n));
init();
int ans=1;
int LLCNT=n;
for(int i=0;i<pcnt;++i){
int now=primelist[i];
int answerA,answerB;
if(primelist[i]<=sq){
cout<<"B "<<now<<endl;
cin>>answerB;//!=0
LLCNT-=answerB;
cout<<"A "<<now<<endl;
cin>>answerA;
int factor=1;
if(answerA!=0){
LLCNT+=answerA;
int base=now;
factor=base;
for(int j=2;base*now<=n;++j){
base*=now;
cout<<"A "<<base<<endl;
cin>>answerA;
if(answerA==1)
factor=base;
else break;
}
ans*=factor;
}
}
else if(ans<=sqrt(n)){
cout<<"B "<<now<<endl;
block[bcnt++]=now;
cin>>answerB;
LLCNT-=answerB;
if(bcnt==BLOCKSIZE||i==pcnt-1){
cout<<"A "<<1<<endl;
int realcnt;
cin>>realcnt;
if(realcnt>LLCNT){
for(int ib=0;ib<bcnt;++ib){
cout<<"A "<<block[ib]<<endl;
cin>>answerA;
if(answerA==1){
ans*=block[ib];
bcnt=0;
break;
}
}
}
bcnt=0;
}
}
else break;
}
cout<<"C "<<ans<<endl;
return 0;
}