2017-2018 ACM-ICPC Latin American Regional Programming Contest

https://codeforces.com/gym/101889

C - Complete Naebbirac's sequence

昨天做的毛子场的C,玛雅信息,直接给抄了?复制粘贴结果还错一发,又说不准前导零,结果又说不准最左侧零,连“0”本身都不准了。

G - Gates of uncertainty

给一棵二叉树,每个节点是一个与非门,其中有些是正常工作,有些是坏的,坏的会恒输出1或者恒输出0,你可以在所有的叶子上填入输出,求有多少种填法使得根节点的输出和正常的时候不一致。

一开始乱dp,用dp[x][0/1]表示被污染的x子树的输出0和1的方案的方法数,然后用fp[x][0/1]表示没有被污染的方案的方法数,gp[x][0/1]表示正常的方案数。但其实题目要求的是不一致的方法数,一开始方向就有问题。

其实设置dp[x][s1][s2]表示x子树输出应为s1,实为s2的方法数,答案就是dp[1][0][1]+dp[1][1][0],考虑转移,实际上应输出以及正常门的实输出就直接按异或门的正常转移就行了,很显然这俩是互相独立的。

问题是那种坏的门,这种就直接让他强制转移就可以了。

直接4重循环,好写好调。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
 
const int MAXN = 1e5 + 5;
 
int n;
int val[MAXN];
int ls[MAXN];
int rs[MAXN];
 
const int MOD = 1e9 + 7;
 
ll dp[MAXN][2][2];
 
bool output(bool input1, bool input2) {
    return !(input1 && input2);
}
 
void dfs(int u) {
    if(u == 0)
        return;
    dfs(ls[u]);
    dfs(rs[u]);
    if(val[u] == -1) {
        for(int ls1 = 0; ls1 <= 1; ++ls1) {
            for(int rs1 = 0; rs1 <= 1; ++rs1) {
                int id1 = output(ls1, rs1);
                for(int ls2 = 0; ls2 <= 1; ++ls2) {
                    for(int rs2 = 0; rs2 <= 1; ++rs2) {
                        int id2 = output(ls2, rs2);
                        dp[u][id1][id2] = (dp[u][id1][id2] + dp[ls[u]][ls1][ls2] * dp[rs[u]][rs1][rs2]) % MOD;
                    }
                }
            }
        }
    } else if(val[u] == 0) {
        for(int ls1 = 0; ls1 <= 1; ++ls1) {
            for(int rs1 = 0; rs1 <= 1; ++rs1) {
                int id1 = output(ls1, rs1);
                for(int ls2 = 0; ls2 <= 1; ++ls2) {
                    for(int rs2 = 0; rs2 <= 1; ++rs2) {
                        int id2 = 0;
                        dp[u][id1][id2] = (dp[u][id1][id2] + dp[ls[u]][ls1][ls2] * dp[rs[u]][rs1][rs2]) % MOD;
                    }
                }
            }
        }
    } else if(val[u] == 1) {
        for(int ls1 = 0; ls1 <= 1; ++ls1) {
            for(int rs1 = 0; rs1 <= 1; ++rs1) {
                int id1 = output(ls1, rs1);
                for(int ls2 = 0; ls2 <= 1; ++ls2) {
                    for(int rs2 = 0; rs2 <= 1; ++rs2) {
                        int id2 = 1;
                        dp[u][id1][id2] = (dp[u][id1][id2] + dp[ls[u]][ls1][ls2] * dp[rs[u]][rs1][rs2]) % MOD;
                    }
                }
            }
        }
    }
}
 
int main() {
#ifdef Yinku
    freopen("Yinku.in", "r", stdin);
#endif // Yinku
    while(~scanf("%d", &n)) {
        for(int i = 1; i <= n; ++i) {
            scanf("%d", &ls[i]);
            scanf("%d", &rs[i]);
            scanf("%d", &val[i]);
        }
 
        memset(dp, 0, sizeof(dp));
 
        dp[0][0][0] = 1;
        dp[0][1][1] = 1;
        dfs(1);
 
        printf("%lld\n", (dp[1][0][1] + dp[1][1][0]) % MOD);
    }
}
上一篇:requests爬虫请求报错:UnicodeEncodeError: 'latin-1' codec can't encode character '\u20


下一篇:mysql 乱码