牛客小白月赛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 }

 

posted @ 2024-06-26 21:33  congmingyige  阅读(5)  评论(0编辑  收藏  举报