#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
typedef pair<double,double> PDD;
typedef vector<int> VI;
const int mod = 1e8;
using ull = unsigned long long;
int n,m;
bool broken[400010];
int a[400010];
int dp[500010][3];
int gp[500010][3];
string s;
int idx =0;
int tree[500010][3];
void build(int root){
idx++;
if(s[root] == '0'){
return;
}
if(s[root] == '1'){
tree[root][0] = idx + 1;
build(idx + 1);
}
if(s[root] == '2'){
tree[root][0] = idx + 1;
build(idx + 1);
tree[root][1] = idx + 1;
build(idx + 1);
}
}
void work(int x){
if(tree[x][1])work(tree[x][1]);
if(tree[x][0])work(tree[x][0]);
int l = tree[x][0];
int r = tree[x][1];
dp[x][0] = max({dp[l][1]+dp[r][2],dp[r][1]+dp[l][2]}) + 1;
dp[x][1] = max({dp[l][0]+dp[r][2],dp[r][0]+dp[l][2]});
dp[x][2] = max({dp[l][0]+dp[r][1],dp[r][0]+dp[l][1]});
gp[x][0] = min({gp[l][1]+gp[r][2],gp[r][1]+gp[l][2]}) + 1;
gp[x][1] = min({gp[l][0]+gp[r][2],gp[r][0]+gp[l][2]});
gp[x][2] = min({gp[l][0]+gp[r][1],gp[r][0]+gp[l][1]});
}
int main(){
cin>>s;
s=" "+s;
build(1);
//cout<<tree[1][0]<<tree[1][1];
//cout<<tree[1][1];
//cout<<idx;
//memset(gp,0x3f,sizeof gp);
//memset(dp,0,sizeof gp);
work(1);
cout<<max({dp[1][0],dp[1][1],dp[1][2]})<<" ";
cout<<min({gp[1][0],gp[1][1],gp[1][2]})<<" ";
}
dp[i][x] 第i个节点颜色为x时 绿色的最多数目
gp同理
——————————————————————————————
学会递归建树的操作,其实和tire树是很像的捏,
这题只需要开节点,并不需要在节点中添加值和内容