我们都做过一道题(?)货币兑换,是用cdq分治来解决不单调的斜率优化

现在它放到了树上..

总之先写下来dp方程,$f[i]=min\{f[j]+(dis[i]-dis[j])*p[i]+q[i]\} ,j是i的祖先,dis[i]-dis[j]<=l[i]$ ,其中dis[i]表示1号点到i号点的距离

可以很明显的看出斜率优化,但我们要放到树上做

于是就运用点分治的思想来找重心(正如普通的cdq是找中点一样)

步骤是这样的:

1.对于根为x的一个子树,我们先找到它的重心rt

2.把rt的子树刨掉,但留下rt,然后递归地再做x,目的是先算出祖先们的答案,为更新孩子们做准备

3.把rt在子树x中的祖先按深度排序,把rt的子树(不包括rt)按照它们最远能到的祖先的深度排序,然后一边插祖先维护一个凸包,一边给孩子统计答案

4.递归地做rt的子节点

斜率优化的细节就不写了(因为全是蒙出来的)

  1. #include<bits/stdc++.h>
  2. #define pa pair<int,int>
  3. #define ll long long
  4. using namespace std;
  5. const int maxn=2e5+,inf=0x3f3f3f3f;
  6.  
  7. inline ll rd(){
  8. ll x=;char c=getchar();int neg=;
  9. while(c<''||c>''){if(c=='-') neg=-;c=getchar();}
  10. while(c>=''&&c<='') x=x*+c-'',c=getchar();
  11. return x*neg;
  12. }
  13.  
  14. struct Edge{
  15. int b,ne;ll l;
  16. }eg[maxn*];
  17. int fa[maxn][],egh[maxn],ect;
  18. int N,NN,dep[maxn],ldep[maxn];
  19. int siz[maxn],root;
  20. int cnt[maxn],tmpl[maxn],tmpr[maxn],pct;
  21. int stk[maxn];
  22. ll dp[maxn],dis[maxn],p[maxn],q[maxn],l[maxn];
  23. bool vis[maxn];
  24.  
  25. void dfs1(int x){
  26. int i;
  27. for(i=;fa[x][i-]&&fa[fa[x][i-]][i-];i++) fa[x][i]=fa[fa[x][i-]][i-];
  28. int y=x;for(ll j=l[x];i>=;i--){
  29. if(fa[y][i]&&dis[y]-dis[fa[y][i]]<=j)
  30. j-=dis[y]-dis[fa[y][i]],y=fa[y][i];
  31. }
  32. if(y!=x) ldep[x]=dep[y];
  33. else ldep[x]=-;
  34.  
  35. for(i=egh[x];i;i=eg[i].ne){
  36. int b=eg[i].b;
  37. dis[b]=dis[x]+eg[i].l;
  38. dep[b]=dep[x]+;
  39. dfs1(b);
  40. }
  41. }
  42.  
  43. void getroot(int x,int smsiz,int &ms,int &root){
  44. siz[x]=;int mm=;
  45. for(int i=egh[x];i;i=eg[i].ne){
  46. int b=eg[i].b;if(vis[b]) continue;
  47. getroot(b,smsiz,ms,root);siz[x]+=siz[b];
  48. mm=max(mm,siz[b]);
  49. }mm=max(mm,smsiz-siz[x]);
  50. if(mm<=ms) ms=mm,root=x;
  51. }
  52. void getson(int x){
  53. tmpr[++pct]=x;
  54. for(int i=egh[x];i;i=eg[i].ne){
  55. int b=eg[i].b;if(vis[b]) continue;
  56. getson(b);
  57. }
  58. }
  59.  
  60. inline bool cmp(int a,int b){
  61. return ldep[a]>ldep[b];
  62. }
  63.  
  64. inline double getk(int a,int b){
  65. return (double)(dp[a]-dp[b])/(dis[a]-dis[b]);
  66. }
  67.  
  68. void cdq(int x,int s){
  69. if(s<=) return;
  70. int rt,ms=inf;
  71. getroot(x,s,ms,rt);
  72. if(x!=rt){
  73. int sms=s,mmm=inf;
  74. for(int i=egh[rt];i;i=eg[i].ne) vis[eg[i].b]=,sms-=siz[eg[i].b];
  75. cdq(x,sms);
  76. }int l=;
  77. for(int i=rt;i!=fa[x][];i=fa[i][]) tmpl[++l]=i;
  78. pct=;
  79. for(int i=egh[rt];i;i=eg[i].ne) getson(eg[i].b);
  80. sort(tmpr+,tmpr+pct+,cmp);
  81.  
  82. int sh=;
  83. for(int i=,j=;i<=pct&&ldep[tmpr[i]]!=-;i++){
  84. for(;j<=l&&dep[tmpl[j]]>=ldep[tmpr[i]];j++){
  85. while(sh>&&getk(stk[sh],stk[sh-])<=getk(stk[sh],tmpl[j])) --sh;
  86. stk[++sh]=tmpl[j];
  87. }
  88. if(sh){
  89. int k=stk[];
  90. if(sh!=){
  91. int a=,b=sh-;
  92. while(a<=b){
  93. int m=(a+b)>>;
  94. if(getk(stk[m],stk[m+])<=p[tmpr[i]]) k=stk[m],b=m-;
  95. else k=stk[m+],a=m+;
  96. }
  97. }
  98. dp[tmpr[i]]=min(dp[tmpr[i]],dp[k]+(dis[tmpr[i]]-dis[k])*p[tmpr[i]]+q[tmpr[i]]);
  99. }
  100. }
  101. for(int i=egh[rt];i;i=eg[i].ne){
  102. cdq(eg[i].b,siz[eg[i].b]);
  103. }
  104. }
  105.  
  106. inline void adeg(int a,int b,int l){
  107. eg[++ect].b=b;eg[ect].l=l;eg[ect].ne=egh[a];egh[a]=ect;
  108. }
  109.  
  110. int main(){
  111. int i,j,k;
  112. N=rd();rd();
  113. for(i=;i<=N;i++){
  114. int a=rd(),b=rd();p[i]=rd(),q[i]=rd(),l[i]=rd();
  115. adeg(a,i,b);fa[i][]=a;
  116. }ldep[]=-;dep[]=;dfs1();
  117. memset(dp,,sizeof(dp));dp[]=;
  118. cdq(,N);
  119. for(i=;i<=N;i++) printf("%lld\n",dp[i]);
  120. return ;
  121. }

bzoj3672/luogu2305 购票 (运用点分治思想的树上cdq分治+斜率优化dp)的更多相关文章

  1. 【BZOJ-3672】购票 树分治 + 斜率优化DP

    3672: [Noi2014]购票 Time Limit: 30 Sec  Memory Limit: 512 MBSubmit: 1177  Solved: 562[Submit][Status][ ...

  2. 【bzoj3672】[Noi2014]购票 斜率优化dp+CDQ分治+树的点分治

    题目描述  给出一棵以1为根的带边权有根树,对于每个根节点以外的点$v$,如果它与其某个祖先$a$的距离$d$不超过$l_v$,则可以花费$p_vd+q_v$的代价从$v$到$a$.问从每个点到1花费 ...

  3. [Noi2014]购票 斜率优化DP+可持久化凸包

    貌似网上大部分题解都是CDQ分治+点分治然后再斜率优化DP,我貌似并没有用这个方法. 这一题跟这题有点像,只不过多了一个l的限制 如果说直接跑斜率优化DP,存储整个序列的话,显然是不行的,如图所示(图 ...

  4. 【uoj#244】[UER #7]短路 CDQ分治+斜率优化dp

    题目描述 给出 $(2n+1)\times (2n+1)$ 个点,点 $(i,j)$ 的权值为 $a[max(|i-n-1|,|j-n-1|)]$ ,找一条从 $(1,1)$ 走到 $(2n+1,2n ...

  5. BZOJ1492:[NOI2007]货币兑换 (CDQ分治+斜率优化DP | splay动态维护凸包)

    BZOJ1492:[NOI2007]货币兑换 题目传送门 [问题描述] 小Y最近在一家金券交易所工作.该金券交易所只发行交易两种金券:A纪念券(以下简称A券)和B纪念券(以下简称B券).每个持有金券的 ...

  6. BZOJ3672: [Noi2014]购票【CDQ分治】【点分治】【斜率优化DP】

    Description 今年夏天,NOI在SZ市迎来了她30周岁的生日.来自全国 n 个城市的OIer们都会从各地出发,到SZ市参加这次盛会. 全国的城市构成了一棵以SZ市为根的有根树,每个城市与它的 ...

  7. UOJ#7 NOI2014 购票 点分治+凸包二分 斜率优化DP

    [NOI2014]购票 链接:http://uoj.ac/problem/7 因为太麻烦了,而且暴露了我很多学习不扎实的问题,所以记录一下具体做法. 主要算法:点分治+凸包优化斜率DP. 因为$q_i ...

  8. BZOJ 3672: [Noi2014]购票 树上CDQ分治

    做这道题真的是涨姿势了,一般的CDQ分治都是在序列上进行的,这次是把CDQ分治放树上跑了~ 考虑一半的 CDQ 分治怎么进行: 递归处理左区间,处理左区间对右区间的影响,然后再递归处理右区间. 所以, ...

  9. BZOJ 3963: [WF2011]MachineWorks [CDQ分治 斜率优化DP]

    传送门 当然了WF的题uva hdu上也有 你的公司获得了一个厂房N天的使用权和一笔启动资金,你打算在这N天里租借机器进行生产来获得收益.可以租借的机器有M台.每台机器有四个参数D,P,R,G.你可以 ...

随机推荐

  1. jenkins 构建后发送钉钉消息通知(插件)

    钉钉,越来越多的公司采用,那么我们在持续集成中,也可以直接选择钉钉插件的,在之前的博客中 ,对发送的钉钉消息进行了定制,那样的话会开启一个新的任务, 其实今天呢,我们可以直接安装一个插件就可以发送了, ...

  2. 【nodejs】让nodejs像后端mvc框架(asp.net mvc )一样处理请求--路由限制及选择篇(2/8)【route】

    文章目录 前情概要 上文中的RouteHandler中有一个重要方法GetActionDescriptor没有贴代码和说,接下来我们就说一说这个方法. 使用controllerName.actionN ...

  3. Ionic 2 官方示例程序 Super Starter

    原文发表于我的技术博客 本文分享了 Ionic 2 官方示例程序 Super Starter 的简要介绍与安装运行的方法,最好的学习示例代码,项目共包含了 14 个通用的页面设计,如:引导页.主页面详 ...

  4. 洛谷P1004 方格取数-四维DP

    题目描述 设有 N \times NN×N 的方格图 (N \le 9)(N≤9) ,我们将其中的某些方格中填入正整数,而其他的方格中则放入数字 00 .如下图所示(见样例): A 0 0 0 0 0 ...

  5. 【CV】ICCV2015_Describing Videos by Exploiting Temporal Structure

    Describing Videos by Exploiting Temporal Structure Note here: it's a learning note on the topic of v ...

  6. Failed to execute goal org.springframework.boot

    报错 [ERROR] Failed to execute goal org.springframework.boot:spring-boot-maven-plugin:1.4.0.RELEASE:ru ...

  7. Windows系统下PHP使用Redis

    参考链接:https://www.cnblogs.com/lhat/p/6402472.html 环境:windows 10  64位操作系统    php 5.4 redis 3.0 1.redis ...

  8. 当返回值为json字符串时 如何获得其中的json数组

    json数据格式 {"IPPORT":"192.168.0.12","time":"2017-04-05 09:12:06&quo ...

  9. PostgreSQL之性能优化(转)

    转载自:https://blog.csdn.net/huangwenyi1010/article/details/72853785 解决问题 前言 PostgreSQL的配置参数作为性能调优的一部分, ...

  10. Python 零基础 快速入门 趣味教程 (咪博士 海龟绘图 turtle) 5. 参数

    上一个教程中,咪博士带大家学习了函数的使用.例如,line_without_moving 函数,可以让海龟先画出一条线段,然后再回来起点. def line_without_moving(): tur ...