zoukankan      html  css  js  c++  java
  • Codeforces Round #649 (Div. 2) E. X-OR 交互 二进制 随机 期望

    LINK:X-OR

    本来是应该昨天晚上发的 可是昨天晚上 做这道题 写了一个分治做法 一直wa

    然后查错 查不出来 心态崩了 想写对拍 发现交互库自己写不出来。

    一系列sb操作 == 我都醉了。

    今天重构了代码 换了另外一种做法就很快就过了。

    考虑怎么做:求出所有位置上的数字是谁 光凭异或是很难异或出来的。

    或许可以快速察觉到一个做法 对于每一位来做 然后 找到第i为为0的是谁 这样就得到了一个nlogn的做法。

    会爆掉询问次数。

    发现如果逐一找到每个位置上是谁的话 更快需要找到0所在。

    考虑如何找0 在已经有一个函数可以帮忙确定某一位是谁的情况下。

    容易得到 随便找个数字开始或 然后 遇到刚好等于自己的 说明 对方是自己的子集 难么进行一次替换。

    最终就会替换到0.

    这样的过程是O(n)+log^2的 最后再来一次O(n)的扫描 就可以通过了。

    可以利用map 来优化询问次数.一开始每一位的确定位置可以直接rand 期望下是很快的。

    考虑分治做法:

    考虑一种确定一个数字是谁的方法:O(n)暴力扫 然后得到的最小值就是自己的值当然0除外.

    那么我们可以拿到一个值 然后 把自己的子集都给搞出来 不断重复这个过程 直至只剩下两个数字。

    每次选取当前二进制下的一半 这样随机的效率较高。

    期望下询问次数也不超过2n+c 所以可以通过 不过不知道为什么我写挂了...

    这里是第一种做法:

    const int MAXN=2050;
    int n,m=11;
    int p[MAXN];
    int sum[MAXN],b[MAXN];
    inline int ask(int i,int j)
    {
    	cout<<"?"<<' '<<i<<' '<<j<<endl;
    	int x;cin>>x;return x;
    }
    inline int re(int x){return rand()%x+1;}
    inline int gs(int x)
    {
    	int ans=0;
    	vep(0,m,i)
    	{
    		int ww=0;
    		if(b[i]!=x)ww=ask(b[i],x);
    		if(ww&(1<<i))ans|=(1<<i);
    	}
    	return ans;
    }
    int main()
    {
    	//freopen("1.in","r",stdin);
    	ios::sync_with_stdio(false);
    	srand(time(0));
    	cin>>n;
    	int cnt=0;
    	while(cnt<m)
    	{
    		int x=re(n);int y=re(n);
    		if(x==y)continue;
    		int ww=ask(x,y);
    		vep(0,m,i)if(!(ww&(1<<i))&&!b[i])
    		{
    			b[i]=x;++cnt;
    		}
    	}
    	cout<<"ww"<<endl;
    	int ww=gs(1),pos=1;
    	rep(2,n,i)
    	{
    		int x=ask(pos,i);
    		if(x<=ww)
    		{
    			pos=i;
    			ww=gs(i);
    		}
    	}
    	rep(1,n,i)if(pos!=i)p[i]=ask(pos,i);
    	cout<<"!";
    	rep(1,n,i)cout<<' '<<p[i];
    	return 0;
    }
    
  • 相关阅读:
    JS中常遇到的浏览器兼容问题和解决方法
    遍历
    深度克隆和浅拷贝
    js数据类型
    js运算符
    理解js中的事件模型
    常见事件总结
    模板方法模式
    适配器模式和外观模式
    命令模式
  • 原文地址:https://www.cnblogs.com/chdy/p/13154462.html
Copyright © 2011-2022 走看看