【原题】
一棵二叉树可以按照如下规则表示成一个由 0、1、2 组成的字符序列,我们称之为“二叉树序列 (S)”:
(S = egin{cases}0,表示该树没有子节点\ 1S_1,表示该树有一个节点,S_1为其子树的二叉树序列\ 2S_1S_2,表示该树由两个子节点,S_1和S_2分别表示其两个子树的二叉树序列end{cases})
例如,下图所表示的二叉树可以用二叉树序列 (S = 21200110) 来表示。
你的任务是要对一棵二叉树的节点进行染色。每个节点可以被染成红色、绿色或蓝色。并且,一个节点与其子节点的颜色必须不同,如果该节点有两个子节点,那么这两个子节点的颜色也必须不同。给定一颗二叉树的二叉树序列,请求出这棵树中最多和最少有多少个点能够被染成绿色。
输入格式
输入只有一行一个字符串 (s),表示二叉树序列。
输出格式
输出只有一行,包含两个数,依次表示最多和最少有多少个点能够被染成绿色。
输入输出样例
输入 #1
1122002010
输出 #1
5 2
说明/提示
数据规模与约定
对于全部的测试点,保证(1≤∣s∣≤5×10^5),(s) 中只含字符 0
1
2
。
【思路】
树形dp简单题
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <list>
#include <map>
#include <iostream>
#include <iomanip>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <unordered_map>
#include <vector>
#define LL long long
#define inf 0x3f3f3f3f
#define INF 0x3f3f3f3f3f3f
#define PI 3.1415926535898
#define F first
#define S second
#define endl '
'
#define lson rt << 1
#define rson rt << 1 | 1
#define f(x, y, z) for (int LL x = (y), __ = (z); x < __; ++x)
#define _rep(i, a, b) for (int i = (a); i <= (b); ++i)
using namespace std;
const int maxn = 5e5 + 7;
const int mod = 1e9 + 7;
int n, m;
string s;
int p = 0, cnt = 1;
int f[maxn * 4][3], g[maxn * 4][3];
struct node
{
int l, r, cnt;
}nd[maxn * 4];
int build(int nw, int pos)
{
if (s[pos] == '0') nd[nw].l = nd[nw].r = -1;
else if (s[pos] == '1')
{
p++;
nd[nw].l = ++cnt;
build(cnt, p);
nd[nw].r = -1;
}
else
{
p++;
nd[nw].l = ++cnt;
build(cnt, p);
p++;
nd[nw].r = ++cnt;
build(cnt, p);
}
return 0;
}
int col(int nw)
{
if (nd[nw].l == -1 && nd[nw].r == -1)
{
f[nw][0] = g[nw][0] = 1;
return 0;
}
else if(nd[nw].r == -1)
{
int v = nd[nw].l;
col(v);
f[nw][0] = max(f[v][1], f[v][2]) + 1;
f[nw][1] = max(f[v][0], f[v][2]);
f[nw][2] = max(f[v][0], f[v][1]);
g[nw][0] = min(g[v][1], g[v][2]) + 1;
g[nw][1] = min(g[v][0], g[v][2]);
g[nw][2] = min(g[v][0], g[v][1]);
return 0;
}
else
{
int l = nd[nw].l, r = nd[nw].r;
col(l);
col(r);
f[nw][0] = max(f[l][1] + f[r][2], f[l][2] + f[r][1]) + 1;
f[nw][1] = max(f[l][0] + f[r][2], f[l][2] + f[r][0]);
f[nw][2] = max(f[l][0] + f[r][1], f[l][1] + f[r][0]);
g[nw][0] = min(g[l][1] + g[r][2], g[l][2] + g[r][1]) + 1;
g[nw][1] = min(g[l][0] + g[r][2], g[l][2] + g[r][0]);
g[nw][2] = min(g[l][0] + g[r][1], g[l][1] + g[r][0]);
return 0;
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cin >> s;
build(1, 0);
col(1);
cout << max(f[1][0], max(f[1][1], f[1][2])) << " " << min(g[1][0], min(g[1][1], g[1][2]))<< endl;
}