牛客小白月赛96
E 最大稳定数值
还真的是离散化。
去"恐离散化",把这道题做了
多写一下这种,处理、代码量比较麻烦,实际上不难想,就是写起来难受的题。否则,面对这样的题,平时不写,手生,实际比赛的时候,就会望而畏惧。
写成一行的形式,an[i] = (an_value[i]>=a[i]);,不要写成if else 四行的形式。
dfs前后几个位置,可以造就很多式子/表达式的填写。
也可以在一次dfs后,记录order顺序,然后直接for i=1~n执行,也相当于跑dfs。
1 #include <bits/stdc++.h> 2 using namespace std; 3 #define LL long long 4 #define ULL unsigned long long 5 6 const LL mod_1=1e9+7; 7 const LL mod_2=998244353; 8 9 const double eps_1=1e-5; 10 const double eps_2=1e-10; 11 12 const int maxn=1e5+10; 13 const LL maxvalue=2e5+10; 14 15 LL a[maxn],fa[maxn],order[maxn],cnt_order=0; 16 17 vector<int> son[maxn]; 18 LL st_value[maxn], ch_value[maxn], an_value[maxn],diff[maxn]; //st:subtree //an:ancestor //ch:child 19 20 bool an[maxn],ch[maxn],vis[maxn]; 21 LL cnt_vis_st[maxn],ls[maxn*2],f[maxn*2],result; 22 map<LL,LL> mv; 23 24 void dfs(int d) 25 { 26 //order[ ++cnt_order ] = d; 27 st_value[d] = a[d]; 28 29 for (auto s:son[d]) 30 { 31 if (fa[s]==0) 32 an_value[s] = 0; 33 else 34 an_value[s] = an_value[d] + a[d]; 35 an[s] = (an_value[s]>=a[s]); 36 37 dfs(s); 38 39 st_value[d] += st_value[s]; 40 cnt_vis_st[d] += cnt_vis_st[s]; 41 } 42 ch_value[d] = st_value[d] - a[d]; 43 ch[d] = (ch_value[d]<=a[d]); 44 vis[d] = (an[d] && ch[d]); 45 cnt_vis_st[d] += (vis[d]==1); 46 47 diff[d] = ch_value[d] - a[d]; ///need positive(not suitable) and change 48 /// st_value[x] need >= diff[d] 49 } 50 51 void update(LL d, LL modify_value) 52 { 53 while (d<=maxvalue) 54 { 55 f[d] += modify_value; 56 d+=(d&-d); 57 } 58 } 59 60 LL getsum(LL d) 61 { 62 LL sum=0; 63 while (d) 64 { 65 sum+=f[d]; 66 d-=(d&-d); 67 } 68 return sum; 69 } 70 71 72 void dfs_find_zc(int d) //zc:zhicheng 73 { 74 ///二叉查找树 / Splay 75 ///树状数组 / 线段树 只能权值在一定范围。离散化? 76 77 ///cal if cut point d and d's subtree 78 result = max(result, getsum(mv[ st_value[d] ]) - cnt_vis_st[d]); 79 80 /// 81 82 if (an[d] && !ch[d]) 83 update( mv[ diff[d] ], 1); 84 85 for (auto s:son[d]) 86 { 87 dfs_find_zc(s); 88 } 89 90 if (an[d] && !ch[d]) 91 update( mv[ diff[d] ], -1); 92 } 93 94 int main() 95 { 96 int n,i,root,cnt_ls=0,value_index=0; 97 cin>>n; 98 for (i=1;i<=n;i++) 99 cin>>a[i]; 100 for (i=1;i<=n;i++) 101 { 102 cin>>fa[i]; 103 son[ fa[i] ].push_back(i); 104 if (fa[i]==0) 105 root = i; 106 } 107 108 memset(cnt_vis_st,0,sizeof(cnt_vis_st)); 109 dfs(root); 110 111 for (i=1;i<=n;i++) 112 { 113 ls[cnt_ls++] = st_value[i]; 114 if (an[i] && !ch[i]) 115 ls[cnt_ls++] = diff[i]; 116 } 117 sort(ls,ls+cnt_ls); 118 for (i=0;i<cnt_ls;i++) 119 if (i==0 || ls[i]!=ls[i-1]) 120 mv[ls[i]] = ++value_index; 121 122 result = 0; 123 dfs_find_zc(root); 124 cout<<result + cnt_vis_st[root]; 125 126 return 0; 127 }