zoukankan      html  css  js  c++  java
  • CF1406E. Deleting Numbers

    题目大意

    交互题

    有一个[1,n]中的数x,要求在10000次操作内找出,有一个集合{1...n}和三种操作

    A:询问集合内a的倍数个数

    B:询问集合内a(a>=2)的倍数个数,同时删掉除x外所有a的倍数

    C:回答

    题解

    在被Good Bye2019打出心里阴影后九个月没打了尝试上分

    由于10000>=9592(质数个数)+171(<=√n的质数的最大指数和)+100(√9592)*2,所以做法一目了然

    简单的思路:删掉所有质数,之后依次确定每个质数的指数

    这样次数至少是个数*2,但是由于>√n的质数只有最多一个,所以可以先求出这个质数,把>√n的每100个分块,删完之后再查询a=1,这样可以用200次额外操作解决

    <=√n的全部删掉后依次确定即可

    code

    #include <bits/stdc++.h>
    #define fo(a,b,c) for (a=b; a<=c; a++)
    #define fd(a,b,c) for (a=b; a>=c; a--)
    #define ll long long
    //#define file
    using namespace std;
    
    int p[100001],n,s,i,j,k,l,len,sum,ls,S,s2,ans;
    bool f[100001];
    
    void init()
    {
    	fo(i,2,n)
    	{
    		if (!f[i]) p[++len]=i;
    		fo(j,1,len)
    		if (1ll*i*p[j]<=n)
    		{
    			f[i*p[j]]=1;
    			if (!(i%p[j])) break;
    		}
    		else break;
    	}
    }
    
    void ask(char ch,int s) {printf("%c %d
    ",ch,s);fflush(stdout);}
    void del(int t) {sum-=f[t];f[t]=0;}
    
    void find()
    {
    	fo(l,1,len)
    	if (p[l]>s) break;
    	
    	S=1;
    	k=0;
    	ls=l-1;
    	fo(i,l,len)
    	{
    		++k;
    		ask('B',p[i]);
    		scanf("%d",&s2);
    		for (j=p[i]; j<=n; j+=p[i]) del(j);
    		
    		if (k==100 || i==len)
    		{
    			ask('A',1);
    			scanf("%d",&s2);
    			if (s2!=sum)
    			{
    				fo(j,ls+1,i)
    				{
    					ask('A',p[j]);
    					scanf("%d",&s2);
    					if (s2==1) {S=p[j];return;}
    				}
    			}
    			k=0,ls=i;
    		}
    	}
    }
    
    int main()
    {
    	scanf("%d",&n);s=floor(sqrt(n));
    	init();
    	fo(i,1,n) f[i]=1;sum=n;
    	
    	find();
    	fo(i,1,len)
    	if (f[p[i]])
    	{
    		ask('B',p[i]);
    		scanf("%d",&s2);
    		for (j=p[i]; j<=n; j+=p[i]) del(j);
    	}
    	
    	ans=S;
    	fo(i,1,len)
    	if (p[i]<=s)
    	{
    		j=p[i],k=1;
    		while (j<=n)
    		{
    			ask('A',j);
    			scanf("%d",&s2);
    			if (s2) ans*=p[i];
    			else break;
    			
    			if (j<=n/p[i]) j*=p[i];
    			else break;
    		}
    	}
    	ask('C',ans);
    	
    	fclose(stdin);
    	fclose(stdout);
    	return 0;
    }
    
  • 相关阅读:
    .NET简谈互操作(七:数据封送之介绍)
    C# utf8编码时转换成shiftjis时出现乱码问题的处理
    .NET简谈特性(代码属性)
    著名Channel 9 主持人Robert Green 采访微软一站式示例代码库录像
    SharePoint 2007运行 Edit In DataSheet 时在IE 6下页面卡死的分析和处理方法
    截图工具
    Resharper上手指南
    .NET简谈互操作(三:基础知识之DllImport特性)
    .NET简谈互操作(五:基础知识之提升平台调用性能)
    深度训练(DotNet专场)
  • 原文地址:https://www.cnblogs.com/gmh77/p/13659973.html
Copyright © 2011-2022 走看看