Codeforces 558D - Guess Your Way Out! II (求区间交,并)

题中给出的每一个区间都可以转化为叶子那层的一个区间,所以步骤就是:

1.对于所有ans=1的区间求区间交,方法很简单就是两个l取最大值,r取最小值,最后答案一定在这里面。

2.对于ans=0的区间,求区间并的补集。方法是用一个pair,对每个区间的左端点附加信息-1,右端点附加信息1,排序后从左往右扫,累加这个附加信息,当累加和等于0时,说明在该点前的所有区间都结束了,那么从这个点到下一个区间的起点这一段是可能有答案的区间。

注意要把总区间的左右端点也加紧取才能保证不遗漏区间。


代码:

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
#include <vector>
#define mp(a,b) make_pair(a,b)
#define pb(a) push_back(a)
#define LL long long

vector <pair<LL,int> > G;
vector <pair<LL,LL> > N;

int main(){
    int H,Q;
    LL L,R;
    scanf("%d%d",&H,&Q);
    L=1;
    for(int i=0;i<H-1;i++){
        L*=2;
    }
    R=L*2-1;
    LL al=L,ar=R;
    for(int i=0;i<Q;i++){
        int lv,k;
        LL l,r;
        scanf("%d%lld%lld%d",&lv,&l,&r,&k);\
        r++;
        for(int i=0;i<H-lv;i++){
            l*=2; r*=2;
        }
        r--;
        if(k){
            al=max(al,l);
            ar=min(ar,r);
        }
        else {
            G.pb(mp(l,-1)); G.pb(mp(r,1));
        }
    }
    G.pb(mp(L-1,0));G.pb(mp(R+1,0));
    if(al>ar) { printf("Game cheated!\n"); return 0; }
    sort(G.begin(),G.end());
    int tot=0;
    for(int i=0;i<G.size()-1;i++){
        tot+=G[i].second;
        if(tot==0){
            N.pb(mp(G[i].first+1,G[i+1].first-1));
        }
    }
    LL num=0;
    LL res=-1;
    for(int i=0;i<N.size();i++){
        LL cl=N[i].first,cr=N[i].second;
        if(cl>cr) continue;
        cl=max(cl,al);
        cr=min(cr,ar);
        if(cr>=cl){
            num+=(cr-cl+1);
            res=cr;
        }
    }
    if(num>1){
        printf("Data not sufficient!\n");
    }
    else if(num==0){
        printf("Game cheated!\n");
    }
    else printf("%lld\n",res);
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值