Description
Input
仅有一行,不超过500000个字符,表示一个二叉树序列。
Output
输出文件也只有一行,包含两个数,依次表示最多和最少有多少个点能够被染成绿色。
记录每个节点染成每种颜色时以此节点为根的子树中绿色节点个数的最大值和最小值
信息由叶节点向上传递
#include<cstdio> int n; int p=0,mxv=0,mnv=2147483647; int m3[]={0,1,2,0,1,2}; char s[500005]; int cmax[500005][3]; int cmin[500005][3]; inline void maxs(int&a,int b){if(a<b)a=b;} inline void mins(int&a,int b){if(a>b)a=b;} void dfs(int w){ p=w; if(s[w]=='0'){ cmax[w][0]=cmin[w][0]=1; }else if(s[w]=='1'){ dfs(w+1); for(int i=0;i<3;i++){ cmin[w][i]=2147483647; for(int j=0;j<3;j++) if(i!=j){ maxs(cmax[w][i],cmax[w+1][j]); mins(cmin[w][i],cmin[w+1][j]); } } cmax[w][0]++; cmin[w][0]++; }else{ dfs(w+1); int r=p+1; dfs(r); for(int i=0;i<3;i++){ cmin[w][i]=2147483647; for(int j=0;j<3;j++) if(i!=j){ int k=m3[i+j]; maxs(cmax[w][i],cmax[w+1][j]+cmax[r][k]); mins(cmin[w][i],cmin[w+1][j]+cmin[r][k]); } } cmax[w][0]++; cmin[w][0]++; } } int main(){ scanf("%s",s); dfs(0); for(int i=0;i<3;i++){ maxs(mxv,cmax[0][i]); mins(mnv,cmin[0][i]); } printf("%d %d\n",mxv,mnv); return 0; }