UOJ268 [清华集训2016] 数据交互 【动态DP】【堆】【树链剖分】【线段树】

匿名 (未验证) 提交于 2019-12-03 00:43:02

题目分析:

不难发现可以用动态DP做。

题目相当于是要我求一条路径,所有与路径有交的链的代价加入进去,要求代价最大。

我们把链的代价分成两个部分:一部分将代价加入$LCA$之中,用$g$数组保存;另一部分将代价加在整条链上,用$d$数组保存。

这时候我们可以发现,一条从$u$到$v$的路径的代价相当于是$d[LCA(u,v)]+\sum_{x \in edge(u,v)}g[x]$。

如果是静态的,可以用树形DP解决。

看过《神奇的子图》的同学都知道,叶子结点是从它的儿子中取两个最大的出来,所以堆维护。

考虑合并。

链从左延申出的最大的$g$的总和记录。链从右延申包括$d$的总和记录,每次向上$update$的时候拼起来与原答案比较即可。

代码:

  1 #include<bits/stdc++.h>   2 using namespace std;   3    4 typedef long long ll;   5    6 const int maxn = 102000;   7    8 int n,m;   9   10 vector <int> g[maxn];  11 int sz[maxn],top[maxn],fa[maxn],dep[maxn],son[maxn],ind[maxn],dr[maxn];  12 int tail[maxn],num;  13   14 struct Query{int from,to,w;}Q[maxn];  15 struct Priority_Queue{  16     priority_queue<ll,vector<ll>,less<ll> > pq,del;  17     void push(ll now){pq.push(now);}  18     void pop(){  19     while(!del.empty() && pq.top() == del.top()) pq.pop(),del.pop();  20     pq.pop();  21     }  22     ll top(){  23     while(!del.empty() && pq.top() == del.top()) pq.pop(),del.pop();  24     if(pq.empty()) return 0;  25     else return pq.top();  26     }  27     ll sec(){  28     while(!del.empty() && pq.top() == del.top()) pq.pop(),del.pop();  29     if(pq.size() ==0) return 0;  30     ll oop = pq.top(); pq.pop();  31     while(!del.empty() && pq.top() == del.top()) pq.pop(),del.pop();  32     if(pq.size() == 0){pq.push(oop);return 0;} 
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!