https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1484
先看出现范围是否矛盾 不矛盾可整合一个新的出现范围 然后再用不出现范围来进一步缩小出现范围即可
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll N=0x3f3f3f3f3f3f3f3f;
const int maxn=1e5+10;
struct node
{
ll l,r;
};
node order[maxn];
ll pre[100],tmp[6*maxn];
int book[6*maxn];
int h,n,tot,len;
void init()
{
int i;
pre[0]=1;
for(i=1;i<=50;i++) pre[i]=2ll*pre[i-1];
}
int main()
{
ll l,r,pl,pr,maxl,minr;
int i,d,a,res;
init();
scanf("%d%d",&h,&n);
maxl=-N,minr=N;
while(n--)
{
scanf("%d%lld%lld%d",&d,&l,&r,&a);
while(d<h) l=2ll*l,r=2ll*r+1,d++;
tmp[++len]=l-1,tmp[++len]=l,tmp[++len]=l+1;
tmp[++len]=r-1,tmp[++len]=r,tmp[++len]=r+1;
if(a) maxl=max(maxl,l),minr=min(minr,r);
else order[++tot].l=l,order[tot].r=r;
}
maxl=max(maxl,pre[h-1]),minr=min(minr,pre[h]-1);
if(maxl>minr) printf("Game cheated!\n");
else
{
sort(tmp+1,tmp+len+1);
len=unique(tmp+1,tmp+len+1)-tmp-1;
for(i=1;i<=tot;i++)
{
pl=lower_bound(tmp+1,tmp+len+1,order[i].l)-tmp;
pr=lower_bound(tmp+1,tmp+len+1,order[i].r)-tmp;
book[pl]++;
book[pr+1]--;
}
for(i=1;i<=len;i++) book[i]+=book[i-1];
for(i=1;i<=len;i++)
{
book[i]=min(book[i],1);
book[i]+=book[i-1];
}
pl=lower_bound(tmp+1,tmp+len+1,maxl)-tmp;
pr=lower_bound(tmp+1,tmp+len+1,minr)-tmp;
res=book[pr]-book[pl-1];
if(res==pr-pl+1) printf("Game cheated!\n");
else
{
if(res+1<pr-pl+1) printf("Data not sufficient!\n");
else
{
for(i=pl;i<=pr;i++)
{
if(book[i]-book[i-1]==0)
{
if(i==1) pl=tmp[1];
else pl=tmp[i-1]+1;
if(i==len) pr=tmp[len];
else pr=tmp[i+1]-1;
break;
}
}
if(pl==pr) printf("%lld\n",pl);
else printf("Data not sufficient!\n");
}
}
}
return 0;
}