1. 程式人生 > 實用技巧 >CF1406E Deleting Numbers

CF1406E Deleting Numbers

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;
}