zoukankan      html  css  js  c++  java
  • Codeforces Round #499 (Div. 2) F. Mars rover_dfs_位运算

    题解:

    首先,我们可以用 dfsdfsO(n)O(n) 的时间复杂度求出初始状态每个点的权值。

    不难发现,一个叶子节点权值的取反会导致根节点的权值取反当且仅当从该叶子节点到根节点这一条链上的每个点的权值都被取反(都被影响到)。而这4种逻辑运算中,NOTNOTXORXOR 是最简单的,即只要2个儿子中的一个儿子的值被取反,该点的值就会被取反。但 ANDANDOROR 存在只修改一个儿子时不会对该点的权值产生影响的情况,这就需要我们进行一下特判。

    我们给每个节点开一个 tagtag 变量, tagtag = falsefalse 的话说明该节点不会随这儿子节点权值的变化而变化,tag=truetag=true 则相反。如果一个节点的 tag=falsetag=false, 那么就没有必要进行特判,直接将所有子节点的 tagtag 设成 falsefalse 即可。

    反之,则对左右儿子进行特判,分别下传标记即可。
    Code:

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    const int maxn = 1002000 + 3;
    int n, ans[maxn], node[maxn],  ch[maxn][2], val[maxn];
    bool lazy[maxn];
    inline int get(char str[]){
        if(str[0] == 'I') return 1;
        if(str[0] == 'N') return 2;
        if(str[0] == 'O') return 3;
        if(str[0] == 'A') return 4;
        if(str[0] == 'X') return 5;
    }
    int dfs1(int u)
    {
        if(node[u] == 1) return val[u] ;
        if(node[u] == 2) return (val[u] = !dfs1(ch[u][0]) );
        if(node[u] == 3) return (val[u] = (dfs1(ch[u][0]) | dfs1(ch[u][1])) );
        if(node[u] == 4) return (val[u] = (dfs1(ch[u][0]) & dfs1(ch[u][1])) );
        if(node[u] == 5) return (val[u] = (dfs1(ch[u][0]) ^ dfs1(ch[u][1])) );
    }
    void dfs2(int u)
    {
        if(lazy[u] == false) {  lazy[ch[u][0]] = lazy[ch[u][1]] = false;}
        else{
            switch(node[u])
            {
                case 2:
                    lazy[ch[u][0]] = true;
                    break;
                case 3:
                    if(val[ch[u][0]]) 
                        lazy[ch[u][1]] = false;
                    else 
                        lazy[ch[u][1]] = true;
                    if(val[ch[u][1]]) 
                        lazy[ch[u][0]] = false;
                    else 
                        lazy[ch[u][0]] = true;
                    break;
                case 4:
                    if(!val[ch[u][0]])
                        lazy[ch[u][1]] = false;
                    else 
                        lazy[ch[u][1]] = true;
                    if(!val[ch[u][1]]) 
                        lazy[ch[u][0]] = false;
                    else 
                        lazy[ch[u][0]] = true;
                    break;
                case 5:
                    lazy[ch[u][0]] = lazy[ch[u][1]] = true; 
                    break;
            }
        }
        lazy[0] = 0;
        if(ch[u][0]) dfs2(ch[u][0]);
        if(ch[u][1]) dfs2(ch[u][1]);
    }
    int main()
    {
        memset(lazy, 1, sizeof(lazy));
        scanf("%d",&n);
        for(int i = 1;i <= n; ++i)
        {
            char str[10]; 
            scanf("%s",str);
            node[i] = get(str);
            if(node[i] == 1)
                scanf("%d",&val[i]);
            else if(node[i] == 2) 
                scanf("%d",&ch[i][0]);
            else 
                scanf("%d%d",&ch[i][0],&ch[i][1]);
        }
        dfs1(1);
        lazy[1] = true;
        dfs2(1);
        for(int i = 1;i <= n; ++i) 
            if(node[i] == 1)  printf("%d",val[1] ^ lazy[i]);
        printf("
    ");
        return 0;
    }
    
  • 相关阅读:
    选项菜单-OptionMenu
    Android Studio教程
    android 使用layer-list
    JavaScript OOP 学习总结
    Android应用中网络请求库Volley的使用
    Android应用中网络请求库Volley的介绍
    Android UI: LinearLayout中layout_weight 属性的使用规则
    Robot Framework 培训
    Begin :SWIFT 基本语法
    树莓派raspberrypi系统安装docker以及编译nginx和php镜像
  • 原文地址:https://www.cnblogs.com/guangheli/p/9845128.html
Copyright © 2011-2022 走看看