ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

CF 1535-Playoff Tournament

2021-06-10 02:04:35  阅读:220  来源: 互联网

标签:tmp cnt rs Tournament tr 1535 Playoff ppp ls


image

题意

给定深度为\(k\)的完全二叉树,每个节点有一个值\(0/1/?\),其中\(0\)代表选左值,\(1\)代表选右值,\(?\)代表二者都选。初始情况下,叶子结点下的节点值为\(1\)。
问每次修改一个节点后,根节点的值为多少。

解法

先根据初始状态建成一颗树,然后每次单点修改,时间复杂度\(O(m * k)\)。

小记

XX,完全自己想出来然后debug出来一道1800分的题目好有成就感(虽然好像原来就应该这样),不管了,睡觉睡觉。,开心。

Code


const int N = 1 << 21;

/*
构建一颗深度为k的完全二叉树,节点保存0/1/?,然后从根节点递归枚举当前可能的结果。
单点修改就可以,时间复杂度O(q * 18);
*/


int n;
char s[N];
char tr[N];
int nn ;
int cnt[N],ppp;


inline int ls(int u) {
    return u << 1;
}
inline int rs(int u) {
    return u << 1 | 1;
}

void modify(int pos,char x) {
    int tmp = nn;
    while(tmp) {
        int now = (1 << (tmp - 1));
        int num = now;
        if(num  < pos) pos -= num;
        else {
            ppp = now + pos - 1;
            tr[now + pos - 1] = x;return ;
        }
        --tmp;
    }
}

ll query(int u) {
    if(u >= n) {
        cnt[u] = 1;
        return 1;
    }
    if(tr[u] == '?') {
        cnt[u] = query(ls(u)) + query(rs(u));
        return cnt[u];
    }else if(tr[u] == '1') {
        cnt[u] = query(rs(u));
        query(ls(u));
        return cnt[u];
    }else if(tr[u] == '0') {
        cnt[u] = query(ls(u));
        query(rs(u));
        return cnt[u];
    }

}

void update() {
    int tmp = ppp;
    if(tr[ppp] == '?') {
        cnt[ppp] = cnt[ls(ppp)] + cnt[rs(ppp)];
    }else if(tr[ppp] == '1') {
        cnt[ppp] = cnt[rs(ppp)];
    }else if(tr[ppp] == '0') {
        cnt[ppp] = cnt[ls(ppp)];
    }
    tmp >>= 1;
    while(tmp) {
        //cnt[tmp] = cnt[ls(tmp)] + cnt[rs(tmp)];
        if(tr[tmp] == '?') cnt[tmp] = cnt[ls(tmp)] + cnt[rs(tmp)];
        else if(tr[tmp] == '1') cnt[tmp] = cnt[rs(tmp)];
        else if(tr[tmp] == '0') cnt[tmp] = cnt[ls(tmp)];
        tmp >>= 1;
    }
}


void solve() {
    cin >> n >> (s + 1);
    int tmp = n;
    nn = n;
    n = 1 << n;
    int idx = 1;
    while(tmp) {
        int now = (1 << (tmp - 1));
        int num = 1 << (tmp - 1);
        while(num--) {
            tr[now++] = s[idx++];
        }
        --tmp;
    }
    int m;cin >> m ;
    query(1);
    while(m--) {
        int pos;char x;cin >> pos >> x;
        modify(pos,x);
        update();
        cout << cnt[1] << endl;
    }
}

标签:tmp,cnt,rs,Tournament,tr,1535,Playoff,ppp,ls
来源: https://www.cnblogs.com/Wise4/p/14869497.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有