zoukankan      html  css  js  c++  java
  • loj2985「WC2019」I 君的商店(二分,思维)

    loj2985「WC2019」I 君的商店(二分,思维)

    loj

    Luogu

    题解时间

    真的有点猛的思维题。

    首先有一个十分简单的思路:

    花费 $ 2N $ 确定一个为 $ 1 $ 的数。

    之后每次随机选择一对没有确定的数 $ x,y $ 与 $ 1 $ 比较,再将 $ x,y $ 相互比较,总能确定其中一个数的值。

    这样是 $ 7N $ 。

    而另一方面,这道题也是正解来自部分分。

    考虑子任务3:

    很明显首先一次比较确定是先0后1还是先1后0,

    之后二分确定分界的位置即可,花费是 $ 3logN $ 。

    观察正解数据范围,正好是 $ 5N+3logN $ 。

    考虑能不能向上面的子任务转化。

    我们发现 $ 7N $ 暴力仅使用后 $ 5N $ 的操作依然可以确定为0的数,最终留下一个0000......11111的序列,进而得解。

    具体实现比较复杂。

    #include<bits/stdc++.h>
    // #include"shop.h"
    using namespace std;
    typedef long long lint;
    int query(int *S, int nS, int *T, int nT);
    int lst1[2],lst2[2];
    int sta[100011],stp;
    int cmp(const int &a,const int &b){lst1[0]=a,lst2[0]=b;return query(lst1,1,lst2,1);}
    int cmp(const int &a,const int &b,const int &c){lst1[0]=a,lst1[1]=b,lst2[0]=c;return query(lst1,2,lst2,1);}
    void fix(int &a,int &b){if(!cmp(a,b)) swap(a,b);}
    void ThirdAvenue(int task_id,int n,int K,int ans[])
    {
    	int l=0,r=0,mid=0,k=0;
    	if(cmp(0,n-1))
    	{
    		l=0,r=n-2;while(l<=r){mid=l+r>>1;cmp(mid,mid+1,n-1)?(k=mid+1,l=mid+1):(r=mid-1);}
    		for(int i=0;i<k;i++) ans[i]=0;for(int i=k+1;i<n;i++) ans[i]=1;
    		ans[k]=K^((n-1-k)&1);
    	}else
    	{
    		l=1,r=n-1;while(l<=r){mid=l+r>>1;cmp(mid-1,mid,0)?(r=mid-1):(k=mid,l=mid+1);}
    		for(int i=0;i<k;i++) ans[i]=1;for(int i=k+1;i<n;i++) ans[i]=0;
    		ans[k]=K^(k&1);
    	}
    }
    void EnergySynergyMatrix(int task_id,int n,int K,int ans[])
    {
    	int x=0,y=1;for(int i=2,z=i;i<n;i++,z=i)
    	{
    		fix(x,z);if(cmp(x,z,y)) ans[x]=0,swap(x,z);
    		else sta[stp++]=y,swap(y,z);
    	}fix(x,y),ans[y]=1;if(!stp){ans[x]=K^1;return;}sta[stp++]=y;
    	int l=0,r=stp-2,mid=0,k=0;while(l<=r){mid=l+r>>1;cmp(sta[mid],sta[mid+1],y)?(k=mid+1,l=mid+1):(r=mid-1);}
    	for(int i=0;i<k;i++) ans[sta[i]]=0;for(int i=k+1;i<stp;i++) ans[sta[i]]=1;
    	int z=sta[k];fix(x,z);
    	if(cmp(x,z,y)) ans[x]=0,ans[z]=K^((stp-1-k)&1);
    	else ans[x]=!(K^((stp-1-k)&1)),ans[z]=1;
    }
    void find_price(int task_id,int n,int K,int ans[])
    {
    	if(task_id==3) return ThirdAvenue(task_id,n,K,ans);
    	else return EnergySynergyMatrix(task_id,n,K,ans);
    }
    
  • 相关阅读:
    生成XML文件
    webService的发布与调用
    does not contain bitcode ShardSDK等三方库
    IOS在Document目录下创建文件夹、保存、读取、以及删除文件
    判断IOS安装后是否是第一次启动
    OC中使用单例模式
    两个时间(日期)段交集判断方法
    $(document).ready vs. $(window).load
    基于vant上传图片添加水印
    常用的正则校验
  • 原文地址:https://www.cnblogs.com/rikurika/p/13299905.html
Copyright © 2011-2022 走看看