558D

来源:互联网 发布:淘宝怎样退货 编辑:程序博客网 时间:2024/06/11 03:43

很好的题

思路参考网上的

首先我们每次处理都直接推到叶子节点
确定的区间我们可以分成两个可能的区间。
比如l,r 确定没有 那么可能的区间就是 l[n],l-1 r+1,r[n]
那么就转化为了有多少个点被覆盖q次的问题了,因为区间太大,我们用map做。

#include <algorithm>#include <iostream>#include <cstring>#include <vector>#include <cstdio>#include <bitset>#include <cmath>#include <queue>#include <stack>#include <map>#include <set>#define FOR(i,a,b) for(long long i=a;i<=b;i++)#define ROF(i,a,b) for(long long i=a;i>=b;i--)#define mem(i,a) memset(i,a,sizeof(i))#define rson mid+1,r,rt<<1|1#define lson l,mid,rt<<1#define mp make_pair#define pb push_back#define ll long long#define LL long longusing namespace std;template <typename T>inline void read(T &_x_){    _x_=0;bool f=false;char ch=getchar();    while (ch<'0'||ch>'9') {if (ch=='-') f=!f;ch=getchar();}    while ('0'<=ch&&ch<='9') {_x_=_x_*10+ch-'0';ch=getchar();}    if(f) _x_=-_x_;}const double eps = 1e-8;const int maxn = 1e5+7;const int mod = 1e9+7;const ll inf = 1e15;ll L[55],R[55];ll n,q,x,y,z,v;map<ll, int >mmp;int main(){    L[1] = R[1] = 1;      for(int i=2;i<=50;i++){          L[i]=L[i-1]<<1;        R[i]=R[i-1]<<1|1;    }    read(n),read(q);    if(q == 0){          if (n == 1)printf("1\n");          else printf("Data not sufficient!\n");          return 0;      }    FOR(i,1,q){        read(x),read(y),read(z),read(v);        while(x<n){            y<<=1;            z=z<<1|1;            x++;        }        if(v){            mmp[y]++, mmp[z+1]--;        }else{              mmp[L[n]]++, mmp[y]--;            mmp[z+1]++, mmp[R[n]+1]--;          }    }    int sum = 0;      ll pre = -1, cnt = 0, ans = 0;       for(auto i = mmp.begin(); i != mmp.end(); i++){          sum += i->second;          if(pre != -1){              cnt += i->first-pre;            ans = pre;        }        if(sum == q) pre = i->first;          else pre = -1;    }      if (cnt == 0)printf("Game cheated!\n");        else if (cnt > 1)printf("Data not sufficient!\n");        else printf("%I64d\n", ans);        return 0;  }