CodeForces - 558DGuess Your Way Out! II(map 扫描线)
- 解题思路:区间覆盖问题,求出被访问过q次的区间。用扫描线区间左端+1,右端-1,区间左闭右开,注意一种特殊情况h=1,q=0
- AC代码
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
#include<vector>
using namespace std;
int main()
{
int h,q;
long long hl=1,hr=1;
map<long long,int>mp;
scanf("%d%d",&h,&q);
for(int i=1;i<h;i++)
hl=2*hl,hr=2*hr+1;
//printf("%lld %lld\n",hl,hr);
if(q==0)
{
if(h==1)
printf("1\n");
else
printf("Data not sufficient!\n");
}
else {
for(int i=0;i<q;i++)
{
int x,ans;
long long l,r;
scanf("%d%lld%lld%d",&x,&l,&r,&ans);
while(x!=h)
{
x++;
l*=2,r=2*r+1;
}
//printf("l=%lld r=%lld\n",l,r);
if(ans)
{
mp[l]++,mp[r+1]--;
//printf("mp[%lld]=%d,mp[%lld]=%d\n",l,mp[l],r+1,mp[r+1]);
}
else
{
mp[hl]++,mp[l]--;
mp[r+1]++,mp[hr+1]--;
//printf("mp[%lld]=%d,mp[%lld]=%d\n",l,mp[l],r+1,mp[r+1]);
}
}
map<long long,int>::iterator it;
int sum=0,num=0,flag=0;
long long beg=-1,end=-1;
for(it=mp.begin();it!=mp.end();it++)
{
//printf("%lld,%d\n",it->first,it->second);
sum+=it->second;
if(sum==q)
{
beg=it->first;
flag=1;
num++;
}
else if(flag==1&&sum<q)
{
flag=0;
end=it->first;
// printf("%lld\n",end);
}
}
// printf("%lld %lld\n",beg,end);
//printf("%d\n",num);
if(num==1&&end-beg==1)
printf("%lld\n",beg);
else if(num>1||end-beg>1)
printf("Data not sufficient!\n");
else if(!num)
printf("Game cheated!\n");
}
return 0;
}