洛谷P3994 Highway(树形DP+斜率优化+可持久化线段树/二分)
2018-01-04 21:57
411 查看
有点类似NOI2014购票
首先有方程$f(i)=min\{f(j)+(dep_i-dep_j)*p_i+q_i\}$
这个显然是可以斜率优化的...
$\frac {f(j)-f(k)}{dep_j-dep_k}<p_i$
$p_i$是单调的,于是可以单调队列,当遍历完一个子树的时候,必须复原单调队列到进入这棵子树前的样子,这个用可持久化线段树维护可持久化数组显然可做...
当然有更聪明的方法。
单调队列队头出去的时候实际上队列信息不会被覆盖,于是恢复左端点只要记录进入当前点前的左端点即可。
右端点可能会被覆盖,但是每次最多覆盖一个点(也就是当前点),于是恢复右端点只需要记录进入当前点前的右端点和被覆盖的值即可。
但是这么做的话无法保证一个点出队入队次数是常数级别的,也就无法保证复杂度是$O(n)$了,所以每次不能一个一个出队(一条链加一朵大菊花就可以卡了),必须二分出队位置,才可以保证复杂度,做到$O(nlogn)$。
但是出题人没有卡暴力出队的做法...我写二分比直接暴力弹出跑得快= =... 事实证明是评测机玄学...有时候跑得快有时候跑得慢
二分:
#include<iostream> #include<cstring> #include<cstdlib> #include<cstdio> #define ll long long using namespace std; const int maxn=1000010, inf=1e9; struct poi{int too, dis, pre;}e[maxn]; int n, x, z, tot, l, r; int p[maxn], Q[maxn], last[maxn], nowl[maxn], nowr[maxn], nowqr[maxn], q[maxn]; ll f[maxn], d[maxn]; inline void read(int &k) { int f=1; k=0; char c=getchar(); while(c<'0' || c>'9') c=='-' && (f=-1), c=getchar(); while(c<='9' && c>='0') k=k*10+c-'0', c=getchar(); k*=f; } inline void add(int x, int y, int z){e[++tot]=(poi){y, z, last[x]}; last[x]=tot;} inline double xl(int j, int k){return 1.0*(f[j]-f[k])/(d[j]-d[k]);} inline void dfs(int x) { nowl[x]=l; while(l<r && p[x]-xl(q[l+1], q[l])>1e-9) l++; if(x!=1) f[x]=f[q[l]]+Q[x]+1ll*(d[x]-d[q[l]])*p[x]; nowr[x]=r; while(l<r && xl(x, q[r])<xl(q[r], q[r-1])) r--; nowqr[x]=q[r+1]; q[++r]=x; for(int i=last[x], too;i;i=e[i].pre) d[too=e[i].too]=d[x]+e[i].dis, dfs(too); l=nowl[x]; q[r]=nowqr[x]; r=nowr[x]; } int main() { read(n); for(int i=2;i<=n;i++) read(x), read(z), add(x, i, z), read(p[i]), read(Q[i]); l=1; r=0; dfs(1); for(int i=2;i<=n;i++) printf("%lld\n", f[i]); }View Code
相关文章推荐
- bzoj3672: [Noi2014]购票(树形DP+斜率优化+可持久化凸包)
- 洛谷P3994【比赛】Highway 【斜率优化】
- 【BZOJ-2653】middle 可持久化线段树 + 二分
- SCU2016-01 I题 二分 + 斜率优化dp
- BZOJ_2726_[SDOI2012]任务安排_斜率优化+二分
- Codeforces Round #271 (Div. 2)E. Pillars(dp+线段树优化)
- bzoj 2653 二分答案+可持久化线段树
- HDU_6070_Dirt Ratio_二分_线段树优化
- [bzoj2726][SDOI2012]任务安排 ——斜率优化,动态规划,二分,代价提前计算
- 环中环 纪中1347 dp+线段树优化 玄学
- hdu6161Big binary tree-(树形dp+空间优化)
- DP的各种优化(动态规划,决策单调性,斜率优化,带权二分,单调栈,单调队列)
- HDU_6070_Dirt Ratio_二分_线段树优化
- 【bzoj2653: middle】二分答案+可持久化线段树
- zoj Special Subsequence 3349 (DP+线段树优化) 好题***
- 1376 最长递增子序列的数量(dp+线段树优化)
- hdu 2829 Lawrence(二维DP+斜率优化)
- BZOJ 2527 Poi2011 Meteors 整体二分+线段树 / 可持久化线段树(MLE)
- BZOJ1044 [HAOI2008]木棍分割(二分答案/单调性优化dp+递推优化)
- [bzoj1044][HAOI2008][木棍分割] (二分+贪心+dp+队列优化)