ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

CF1406E Deleting Numbers 题解

2021-11-16 08:32:59  阅读:155  来源: 互联网

标签:return rs int 题解 质数 CF1406E read Deleting void


Codeforces
Luogu

Description.

交互,初始有一个集合 \(S=\{1,2,\cdots,n\}\),你需要询问一个数 \(x\)。
你可以进行三种询问:

  1. 问有多少个数是 \(a\) 的倍数
  2. 问有多少个数是 \(a\) 的倍数,并把 \(a\) 倍数删除,\(x\) 无法被删除
  3. 回答你找到了 \(x\)。

\(n\le 10^5,\text{limit}\le 10000\)

Solution.

首先肯定大质数、小质数分别处理。
小质数肯定可以随便处理,因为总个数不超过 \(\mathcal O(\sqrt n)\)。
就直接先消,然后枚举指数。

主要是大质数怎么处理。
如果有小质数,那每个大质数 \(a\) 的倍数除了 \(a\) 和 \(x\) 其他都被消了。
所以可以 \(1\) 次判断是否存在 \(a|x\)
如果没有小质数,相当于答案是个质数,此时我们无法按照之前的方法判断。
有个朴素的想法是删一次问一次,这样是 \(O(2n)\) 的,无法通过。
考虑分块,对整块问一次,如果有再继续问,这样就变成 \(O(n+2\sqrt n)\) 了。

Coding.

点击查看代码
//Coded by Kamiyama_Shiki on 2021.11.15 {{{
//是啊……你就是那只鬼了……所以被你碰到以后,就轮到我变成鬼了
#include<bits/stdc++.h>
#define debug(...) fprintf(stderr,__VA_ARGS__)
using namespace std;typedef long long ll;
template<typename T>inline void read(T &x)
{
	x=0;char c=getchar(),f=0;
	for(;c<48||c>57;c=getchar()) if(!(c^45)) f=1;
	for(;c>=48&&c<=57;c=getchar()) x=(x<<1)+(x<<3)+(c^48);
	f?x=-x:x;
}
template<typename T,typename...L>inline void read(T &x,L&...l) {read(x),read(l...);}//}}}
const int N=100005;int n;
const int V=N;int pr[V],pc,ls[V];char pv[V];//prinit{{{
inline void prinit(int n=V-1)
{
	pv[1]=1,ls[1]=0;for(int i=1;i<=n;i++)
	{
		if(!pv[i]) pr[++pc]=i,ls[i]=i;
		for(int j=1;j<=pc&&i*pr[j]<=n;j++) {pv[i*pr[j]]=1;if(i%pr[j]==0) break;}
	}
}//}}}
inline int A(int x)
{
	if(x>n) return 0;
	printf("A %d\n",x),fflush(stdout);
	int w;return read(w),w;
}
inline int B(int x)
{
	if(x>n) return 0;
	printf("B %d\n",x),fflush(stdout);
	int w;return read(w),w;
}
inline void C(int x) {printf("C %d\n",x),fflush(stdout);}
int main()
{
	int rs=1,wh=1;read(n),prinit(n);
	for(int i=1;i<=pc&&pr[i]*pr[i]<=n;i++)
	{
		int x=pr[i],nw=0;B(pr[i]),nw=A(pr[i]);
		wh=i+1;while(nw) rs*=pr[i],nw=A(x*=pr[i]);
	}
	if(rs!=1)
	{
		for(int i=wh;i<=pc;i++) if(A(pr[i])>1) return C(pr[i]*rs),0;
		return C(rs),0;
	}
	for(int l=wh,r=l+99,now=A(1),nx;l<=pc;l+=100,r+=100,now=nx)
	{
		for(int i=l;i<=r&&i<=pc;i++) B(pr[i]);
		nx=A(1);if(now==nx+min(r,pc)-l+1) continue;
		for(int i=l;i<=r&&i<=pc;i++) if(A(pr[i])) return C(pr[i]),0;
	}return C(1),0;
}

标签:return,rs,int,题解,质数,CF1406E,read,Deleting,void
来源: https://www.cnblogs.com/pealfrog/p/15559418.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有