题目大意:给定一棵树,选定一棵子树中的一些点,薪水和不能超过m,求点的数量*子树根节点的领导能力的最大值

考虑对于每一个节点,我们维护一种数据结构,在当中贪心寻找薪金小的雇佣。

每一个节点暴力重建一定不行。我们考虑可并数据结构。每一个节点将子节点的信息直接合并就可以

能够用启示式合并的Treap。也能够用可并堆

今天特意去学了这玩应0.0 先写了左偏树 然后又写了下随机堆…… 后者速度上更快一些 只是建议从左偏树開始学起

总之平衡树常数各种大就是了0.0

Treap+启示式合并

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<iostream>
  4. #include<algorithm>
  5. #define M 100100
  6. using namespace std;
  7. typedef long long ll;
  8. struct abcd{
  9. abcd *ls,*rs;
  10. int key;
  11. int cnt,siz;
  12. ll num,sum;
  13. abcd (ll x,int y);
  14. void Maintain();
  15. }*null=new abcd(0,0),*tree[M];
  16. struct edge{
  17. int to,next;
  18. }table[M];
  19. int head[M],tot;
  20. int n,root;
  21. ll m,ans,leadership[M];
  22. void Add(int x,int y)
  23. {
  24. table[++tot].to=y;
  25. table[tot].next=head[x];
  26. head[x]=tot;
  27. }
  28. abcd :: abcd(ll x,int y)
  29. {
  30. ls=rs=null;
  31. sum=x*y;
  32. num=x;
  33. cnt=siz=y;
  34. key=y?rand():0;
  35. }
  36. void abcd :: Maintain()
  37. {
  38. siz=ls->siz+rs->siz+cnt;
  39. sum=ls->sum+rs->sum+num*cnt;
  40. }
  41. void Zig(abcd *&x)
  42. {
  43. abcd *y=x->ls;
  44. x->ls=y->rs;
  45. y->rs=x;
  46. x=y;
  47. x->rs->Maintain();
  48. }
  49. void Zag(abcd *&x)
  50. {
  51. abcd *y=x->rs;
  52. x->rs=y->ls;
  53. y->ls=x;
  54. x=y;
  55. x->ls->Maintain();
  56. }
  57. void Insert(abcd *&x,ll y,int z)
  58. {
  59. if(x==null)
  60. {
  61. x=new abcd(y,z);
  62. return ;
  63. }
  64. if(y==x->num)
  65. x->cnt+=z;
  66. else if(y<x->num)
  67. {
  68. Insert(x->ls,y,z);
  69. if(x->ls->key>x->key)
  70. Zig(x);
  71. }
  72. else
  73. {
  74. Insert(x->rs,y,z);
  75. if(x->rs->key>x->key)
  76. Zag(x);
  77. }
  78. x->Maintain();
  79. }
  80. int Query(abcd *x,ll y)
  81. {
  82. if(x==null)
  83. return 0;
  84. ll temp=x->ls->sum;int re=0;
  85. if(y<=temp) return Query(x->ls,y);
  86. re+=x->ls->siz;y-=temp;
  87. if(y<=x->num*x->cnt)
  88. return re+y/x->num;
  89. re+=x->cnt;y-=x->num*x->cnt;
  90. return re+Query(x->rs,y);
  91. }
  92. void Decomposition(abcd *&x,int y)
  93. {
  94. if(x==null)
  95. return ;
  96. Decomposition(x->ls,y);
  97. Decomposition(x->rs,y);
  98. Insert(tree[y],x->num,x->cnt);
  99. delete x;
  100. x=null;
  101. }
  102. void Tree_DP(int x)
  103. {
  104. int i;
  105. for(i=head[x];i;i=table[i].next)
  106. {
  107. Tree_DP(table[i].to);
  108. if(tree[x]->siz<tree[table[i].to]->siz)
  109. swap(tree[x],tree[table[i].to]);
  110. Decomposition(tree[table[i].to],x);
  111. }
  112. ans=max(ans,leadership[x]*Query(tree[x],m));
  113. }
  114. int main()
  115. {
  116.  
  117. //freopen("2809.in","r",stdin);
  118. //freopen("2809.out","w",stdout);
  119.  
  120. int i,fa;
  121. ll x;
  122. cin>>n>>m;
  123. for(i=1;i<=n;i++)
  124. {
  125. scanf("%d%lld%lld",&fa,&x,&leadership[i]);
  126. if(!fa) root=i;
  127. else Add(fa,i);
  128. tree[i]=new abcd(x,1);
  129. }
  130. Tree_DP(root);
  131. cout<<ans<<endl;
  132. }
  133. //lld!!

左偏树

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<iostream>
  4. #include<algorithm>
  5. #define M 100100
  6. using namespace std;
  7. struct abcd{
  8. abcd *ls,*rs;
  9. int num,h;
  10. abcd(int x);
  11. }*null=new abcd(0),*tree[M];
  12. struct edge{
  13. int to,next;
  14. }table[M];
  15. int head[M],tot;
  16. int n,m,root,leadership[M],sum[M],size[M];
  17. long long ans;
  18. void Add(int x,int y)
  19. {
  20. table[++tot].to=y;
  21. table[tot].next=head[x];
  22. head[x]=tot;
  23. }
  24. abcd :: abcd(int x)
  25. {
  26. ls=rs=null;
  27. num=x;
  28. if(x) h=0;
  29. else h=-1;
  30. }
  31. abcd* Merge(abcd *x,abcd *y)
  32. {
  33. if(x==null) return y;
  34. if(y==null) return x;
  35. if(x->num<y->num)
  36. swap(x,y);
  37. x->rs=Merge(x->rs,y);
  38. if(x->ls->h<x->rs->h)
  39. swap(x->ls,x->rs);
  40. x->h=x->rs->h+1;
  41. return x;
  42. }
  43. void Tree_DP(int x)
  44. {
  45. int i;
  46. for(i=head[x];i;i=table[i].next)
  47. {
  48. Tree_DP(table[i].to);
  49. tree[x]=Merge(tree[x],tree[table[i].to]);
  50. sum[x]+=sum[table[i].to];
  51. size[x]+=size[table[i].to];
  52. while(sum[x]>m)
  53. {
  54. sum[x]-=tree[x]->num;
  55. --size[x];
  56. tree[x]=Merge(tree[x]->ls,tree[x]->rs);
  57. }
  58. }
  59. ans=max(ans,(long long)size[x]*leadership[x]);
  60. }
  61. int main()
  62. {
  63. int i,fa,x;
  64. cin>>n>>m;
  65. for(i=1;i<=n;i++)
  66. {
  67. scanf("%d%d%d",&fa,&x,&leadership[i]);
  68. if(!fa) root=i;
  69. else Add(fa,i);
  70. tree[i]=new abcd(x);
  71. sum[i]=x;
  72. size[i]=1;
  73. }
  74. Tree_DP(root);
  75. cout<<ans<<endl;
  76. }

随机堆

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<iostream>
  4. #include<algorithm>
  5. #define M 100100
  6. using namespace std;
  7. struct abcd{
  8. abcd *ls,*rs;
  9. int num;
  10. abcd(int x);
  11. }*null=new abcd(0),*tree[M];
  12. struct edge{
  13. int to,next;
  14. }table[M];
  15. bool son;
  16. int head[M],tot;
  17. int n,m,root,leadership[M],sum[M],size[M];
  18. long long ans;
  19. void Add(int x,int y)
  20. {
  21. table[++tot].to=y;
  22. table[tot].next=head[x];
  23. head[x]=tot;
  24. }
  25. abcd :: abcd(int x)
  26. {
  27. ls=rs=null;
  28. num=x;
  29. }
  30. abcd* Merge(abcd *x,abcd *y)
  31. {
  32. if(x==null) return y;
  33. if(y==null) return x;
  34. if(x->num<y->num)
  35. swap(x,y);
  36. if(son^=1)
  37. x->rs=Merge(x->rs,y);
  38. else
  39. x->ls=Merge(x->ls,y);
  40. return x;
  41. }
  42. void Tree_DP(int x)
  43. {
  44. int i;
  45. for(i=head[x];i;i=table[i].next)
  46. {
  47. Tree_DP(table[i].to);
  48. tree[x]=Merge(tree[x],tree[table[i].to]);
  49. sum[x]+=sum[table[i].to];
  50. size[x]+=size[table[i].to];
  51. while(sum[x]>m)
  52. {
  53. sum[x]-=tree[x]->num;
  54. --size[x];
  55. tree[x]=Merge(tree[x]->ls,tree[x]->rs);
  56. }
  57. }
  58. ans=max(ans,(long long)size[x]*leadership[x]);
  59. }
  60. int main()
  61. {
  62. int i,fa,x;
  63. cin>>n>>m;
  64. for(i=1;i<=n;i++)
  65. {
  66. scanf("%d%d%d",&fa,&x,&leadership[i]);
  67. if(!fa) root=i;
  68. else Add(fa,i);
  69. tree[i]=new abcd(x);
  70. sum[i]=x;
  71. size[i]=1;
  72. }
  73. Tree_DP(root);
  74. cout<<ans<<endl;
  75. }

BZOJ 2809 APIO2012 dispatching Treap+启示式合并 / 可并堆的更多相关文章

  1. BZOJ 2809 APIO 2012 dispatching 平衡树启示式合并

    题目大意:给出一棵树,每个节点有两个值,各自是这个忍者的薪水和忍者的领导力.客户的惬意程度是这个点的领导力乘可以取得人数.前提是取的人的薪水总和不超过总的钱数. 思路:仅仅能在子树中操作.贪心的想,我 ...

  2. BZOJ 2809: [Apio2012]dispatching( 平衡树 + 启发式合并 )

    枚举树上的每个结点做管理者, 贪心地取其子树中薪水较低的, 算出这个结点为管理者的满意度, 更新答案. 用平衡树+启发式合并, 时间复杂度为O(N log²N) ------------------- ...

  3. bzoj 2809: [Apio2012]dispatching -- 可并堆

    2809: [Apio2012]dispatching Time Limit: 10 Sec  Memory Limit: 128 MB Description 在一个忍者的帮派里,一些忍者们被选中派 ...

  4. BZOJ 2809: [Apio2012]dispatching(左偏树)

    http://www.lydsy.com/JudgeOnline/problem.php?id=2809 题意: 思路:最简单的想法就是枚举管理者,在其子树中从薪水低的开始选起,但是每个节点都这样处理 ...

  5. BZOJ 2809 [Apio2012]dispatching(斜堆+树形DP)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2809 [题目大意] 给出一棵树,求出每个点有个权值,和一个乘算值,请选取一棵子树, 并 ...

  6. bzoj 2809: [Apio2012]dispatching

    #include<cstdio> #include<algorithm> #define M 1000005 using namespace std; long long an ...

  7. BZOJ 2809: [Apio2012]dispatching [斜堆]

    题意:主席树做法见上一题 我曾发过誓再也不写左偏树(期末考试前一天下午5个小时没写出棘手的操作) 于是我来写斜堆啦 从叶子往根合并,维护斜堆就行了 题目连拓扑序都给你了... 说一下斜堆的操作: 合并 ...

  8. BZOJ 2809: [Apio2012]dispatching(可并堆 左偏树板题)

    这道题只要读懂题目一切好说. 给出nnn个点的一棵树,每一个点有一个费用vvv和一个领导力aaa,给出费用上限mmm.求下面这个式子的最大值ax∗∣S∣ ( S⊂x的子树, ∑iv[i]≤m )\la ...

  9. BZOJ 2809: [Apio2012]dispatching [主席树 DFS序]

    传送门 题意:查询树上根节点值*子树中权值和$\le m$的最大数量 最大值是多少 求$DFS$序,然后变成区间中和$\le m$最多有几个元素,建主席树,然后权值线段树上二分就行了 $WA$:又把边 ...

随机推荐

  1. 多文件上传组件FineUploader使用心得

    原文 多文件上传组件FineUploader使用心得 做Web开发的童鞋都知道,需要经常从客户端上传文件到服务端,当然,你可以使用<input type="file"/> ...

  2. 12.5.3 UNIVERSAL:最终的祖先类:

    <pre name="code" class="html">12.5.3 UNIVERSAL:最终的祖先类: 你可以把 UNIVERSAL 看作最终 ...

  3. __autoload()方法

    php中__autoload()方法详解 PHP在魔术函数__autoload()方法出现以前,如果你要在一个程序文件中实例化100个对象,那么你必须用include或者require包含进来100个 ...

  4. js数组基础整理

    首页: 主要整理了一下数组中常用的一些基础知识,代码都是自己手敲,有不对的地方希望能指出,目前只有4篇,后续会不断的增加这一板块. 由于少于100字不能发所以把一些最基本的创建数组也写上. // 创建 ...

  5. delphi中左右翻转窗体(修改EXStyle)

    unit Unit1; interface uses  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Form ...

  6. HTML5 Canvas中9宫格的坑

    近期小鸟情人游戏上了手机qq空间,一个3岁的游戏来了她的第二春.为了能有更好的表现,我们对其进行了一次改版. 改版当中一项就是对原来的弹出框样式进行改进.将大块木板材质改成纯色(边框为圆角金属材质)样 ...

  7. 男性在下一100层【第三层】——高仿手机银行client接口

    前言: 从<男性在下一100层>系列博文[二楼]现在出版了整整三个月后,.从上述观点和这么多朋友的意见还是比较喜欢真实类的博文. 毕竟我们都叫"攻城狮".所以要看是否这 ...

  8. VS关闭Browser Link

    原文:VS关闭Browser Link 这是VS2013的一个新功能,叫Browser Link,基于SignalR. 它可以实现VS IDE和你的程序的双向通讯,在IDE编辑代码即刻将修改发送到浏览 ...

  9. 我在知乎上关于Laser200/310电脑的文章。

    我是30年前从Laser-310起步的,我来回答这个问题. 主要硬件规格: CPU:Z-80A/4.7MHz主频 16K RAM + 2K Video RAM 16K ROM 磁带输出:波特率300 ...

  10. SAP屏幕框架的创建

    1.创建包括文本的基本框架 REPORT ztest_sum. TABLES:mara,syst. WITH FRAME TITLE mytitle. "mytitle是框架上的文本 ) A ...