Codeforces Round #312 (Div. 2) D. Guess Your Way Out! II

来源:互联网 发布:淘宝的化妆品是正品吗 编辑:程序博客网 时间:2024/04/30 07:05

题意:有一棵高为h的树,出口在叶子节点上,n代表这棵树的高度,q代表q个判断,判断的样式是,i,L,R,ans,判断出口在第i层的祖宗节点是否在(L,R)中,ans == 0 代表不在,ans == 1 代表在。然后根据这q个判断,问:是否只有一个出口,如果只有一个出口,输出出口的位置,如果没有出口,输出Game cheated!,如果有多个出口,输出Data not sufficient!。

思路:首先查询只有10^5个,就代表可以把这些查询离散化了,每一个判断都是可以映射到叶子节点那一层,所以先把所有判断映射到叶子节点那一层,然后再离散化,这里离散注意一点就是如果两个点之间的距离大于2的话,需要在中间间隔两个点,因为在这题一个点和两个点是有区别的,两个点和更多点是没有区别的,离散化之后最多就只有4*10^5个点,所以就可以处理了。

http://codeforces.com/contest/558/problem/D

#include <map>#include <queue>#include <cmath>#include <cstdio>#include <cstring>#include <cstdlib>#include <iostream>#include <algorithm>using namespace std;const int MAXN = 100005;typedef long long LL;struct Query {    int r;    LL x,y;}q[MAXN];int a[1000005];long long A[1000005];long long pos[1000005];int n,m;int tot = 0;map<LL,int>mp;void input() {    int r,level;    LL x,y;    for(int i = 1 ; i <= m ; i++) {        scanf("%d %I64d %I64d %d",&level,&x,&y,&r);        for(int j = level + 1 ; j <= n ; j++) {            x = x * (LL)2;            y = y * (LL)2 + (LL)1;        }        q[i].x = x;        q[i].y = y;        q[i].r = r;        A[i*2-1] = x;        A[i*2] = y;    }}void solve() {    memset(a,0,sizeof(a));    A[0] = (LL)1<<(n-1);    sort(A+1,A+1+2*m);    mp.clear();    tot = 1;    mp[A[0]] = 1;    pos[tot] = A[1];    A[2*m+1] = ((LL)1<<n)-(LL)1;    for(int i = 1 ; i <= 2 * m + 1; i ++) {        if(A[i] - A[i-1] > 2) {            tot = tot + 3;            mp[A[i]] = tot;            pos[tot] = A[i];        }        else if(A[i] - A[i-1] == 2){            tot = tot + 2;            mp[A[i]] = tot;             pos[tot-1] = A[i] - 1;            pos[tot] = A[i];        }        else if(A[i] - A[i-1] == 1) {            tot = tot + 1;            mp[A[i]] = tot;            pos[tot] = A[i];        }    }    for(int i = 1 ; i <= m ; i++) {        int x = mp[q[i].x];        int y = mp[q[i].y];        if(q[i].r == 1) {            a[1] ++;            a[x] --;            a[y+1] ++;            a[tot+1] --;        }        else {            a[x] ++;            a[y+1] --;        }    }    int cnt = 0;    int position;    for(int i = 1 ; i <= tot ; i++) {        a[i] += a[i-1];        if(a[i] == 0) {            cnt ++;            position = i;        }    }    if(cnt == 0) {        puts("Game cheated!");    }    else if(cnt >= 2){        puts("Data not sufficient!");    }    else {        if(n == 1) {            puts("1");            return ;        }        printf("%I64d\n",pos[position]);    }}int main(void) {    //freopen("a.in","r",stdin);    while(~scanf("%d %d",&n,&m)) {        input();        solve();    }    return 0;}
0 0
原创粉丝点击