题目大意:给出一棵树,每个节点有两个值,各自是这个忍者的薪水和忍者的领导力。客户的惬意程度是这个点的领导力乘可以取得人数。前提是取的人的薪水总和不超过总的钱数。

思路:仅仅能在子树中操作。贪心的想,我们仅仅要这个子树中cost最小的那些点就能够了。

所以就深搜一次。每到一个节点上。把自己和全部子节点的平衡树启示式和并,然后保留不超过总钱数的人数。统计。数据范围比較大,能开long long的地方不要吝啬。

PS:吐槽一下,一開始这个题一直TTT。我以为是我常数写的太大了。别人都用左偏堆写。是不是平衡树已经成为了时代的眼泪了。

。。

后来我搞到了測点。跑了一下第一组数据等了1分多钟都没出解。

我感觉我又要重写了。就出去转转。十分钟之后我回来发现竟然出解了。并且竟然还对了!!

然后我细致看了一遍程序。

。发现是启示式合并写反了。。。。写反了。。。反了。。。

了。。。

CODE:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define MAX 100010
using namespace std; struct Complex{
long long cost,leader;
}point[MAX]; struct Treap{
int random,size,cnt;
long long val,sum;
Treap *son[2]; Treap(long long _) {
val = sum = _;
size = cnt = 1;
random = rand();
son[0] = son[1] = NULL;
}
int Compare(long long x) {
if(x == val) return -1;
return x > val;
}
void Maintain() {
size = cnt;
sum = val * cnt;
if(son[0] != NULL) size += son[0]->size,sum += son[0]->sum;
if(son[1] != NULL) size += son[1]->size,sum += son[1]->sum;
}
}*tree[MAX]; long long points,money;
int head[MAX],total;
int next[MAX << 1],aim[MAX << 1]; long long ans; inline void Add(int x,int y)
{
next[++total] = head[x];
aim[total] = y;
head[x] = total;
} inline void Rotate(Treap *&a,bool dir)
{
Treap *k = a->son[!dir];
a->son[!dir] = k->son[dir];
k->son[dir] = a;
a->Maintain(),k->Maintain();
a = k;
} inline void Insert(Treap *&a,long long x)
{
if(a == NULL) {
a = new Treap(x);
return ;
}
int dir = a->Compare(x);
if(dir == -1) ++a->cnt;
else {
Insert(a->son[dir],x);
if(a->son[dir]->random > a->random)
Rotate(a,!dir);
}
a->Maintain();
} inline int FindMax(Treap *a)
{
return a->son[1] == NULL ? a->val:FindMax(a->son[1]);
} inline void Delete(Treap *&a,long long x)
{
int dir = a->Compare(x);
if(dir != -1) Delete(a->son[dir],x);
else {
if(a->cnt > 1) --a->cnt;
else {
if(a->son[0] == NULL) a = a->son[1];
else if(a->son[1] == NULL) a = a->son[0];
else {
bool _ = (a->son[0]->random > a->son[1]->random);
Rotate(a,_);
Delete(a->son[_],x);
}
}
}
if(a != NULL) a->Maintain();
} void Transfrom(Treap *&from,Treap *&aim)
{
if(from == NULL) return ;
Transfrom(from->son[0],aim);
Transfrom(from->son[1],aim);
for(int i = 1; i <= from->cnt; ++i)
Insert(aim,from->val);
delete from;
from = NULL;
} void DFS(int x)
{
tree[x] = new Treap(point[x].cost);
if(point[x].cost <= money)
ans = max(ans,(long long)point[x].leader);
if(!head[x])
return ;
for(int i = head[x]; i; i = next[i]) {
DFS(aim[i]);
if(tree[x]->size < tree[aim[i]]->size)
swap(tree[x],tree[aim[i]]);
Transfrom(tree[aim[i]],tree[x]);
}
while(tree[x]->sum > money)
Delete(tree[x],FindMax(tree[x]));
ans = max(ans,(long long)tree[x]->size * point[x].leader);
} int main()
{
cin >> points >> money;
for(int x,i = 1; i <= points; ++i) {
scanf("%d%lld%lld",&x,&point[i].cost,&point[i].leader);
Add(x,i);
}
DFS(0);
cout << ans << endl;
return 0;
}

BZOJ 2809 APIO 2012 dispatching 平衡树启示式合并的更多相关文章

  1. BZOJ 2809 APIO2012 dispatching Treap+启示式合并 / 可并堆

    题目大意:给定一棵树,选定一棵子树中的一些点,薪水和不能超过m,求点的数量*子树根节点的领导能力的最大值 考虑对于每一个节点,我们维护一种数据结构,在当中贪心寻找薪金小的雇佣. 每一个节点暴力重建一定 ...

  2. BZOJ 2733 HNOI 2012 永无乡 平衡树启示式合并

    题目大意:有一些岛屿,一開始由一些无向边连接. 后来也有不断的无向边增加,每个岛屿有个一独一无二的重要度,问随意时刻的与一个岛屿联通的全部岛中重要度第k大的岛的编号是什么. 思路:首先连通性一定要用并 ...

  3. bzoj 2809 左偏树\平衡树启发式合并

    首先我们对于一颗树,要选取最多的节点使得代价和不超过m,那么我们可以对于每一个节点维护一个平衡树,平衡树维护代价以及代价的和,那么我们可以在logn的时间内求出这个子树最多选取的节点数,然后对于一个节 ...

  4. 【BZOJ 2809】 [Apio2012]dispatching

    Description 在一个忍者的帮派里,一些忍者们被选中派遣给顾客,然后依据自己的工作获取报偿.在这个帮派里,有一名忍者被称之为 Master.除了 Master以外,每名忍者都有且仅有一个上级. ...

  5. APIO 2012 派遣(可并堆)

    APIO 2012 派遣(可并堆) 给定一棵N个点的树和M,每个点有两个权值ai,bi,每次可以选择一个点x,然后在这个点的子树中选若干点(可以不选自己),使得这些点的\(\sum b_i<=M ...

  6. 【BZOJ 2809】【APIO 2012】dispatching

    昨天晚上zyf神犇问我的题,虽然我太弱参加不了APIO但也做一做吧. 用小数据拍了无数次总是查不出错来,交上去就WA,后来用国内数据测发现是主席树上区间相减的值没有用long long存,小数据真是没 ...

  7. 「BZOJ 2809」「APIO 2012」Dispatching「启发式合并」

    题意 给定一个\(1\)为根的树,每个点有\(c,w\)两个属性,你需要从某个点\(u\)子树里选择\(k\)个点,满足选出来的点\(\sum_{i=1}^k w(i)\leq m\),最大化\(k\ ...

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

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

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

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

随机推荐

  1. 计算机/ARM 系统

    这方面知识,自己有了大概了解,可以再没有重要急需学习的安排时,不时的翻翻这方面的书.本能力属于重要但不急需的能力

  2. MySQL 之Navicat Premium 12安装使用、pymysql模块使用、sql注入问题的产生与解决

    本文内容提要: Navicat Premium 12 的介绍.使用. pymysql模块的使用 sql注入问题的产生与解决 -------------------------------------- ...

  3. Onenote代码高亮的实现方法

    最终效果图 最终的效果图如下: VBA的编写参考 主要参考的是这篇博客中的思路:如何在Word中排出漂亮的代码 将VBA脚本复制到Word中并设置快捷键 Alt+F11 打开Word中的 VBS,将下 ...

  4. Java并发编程的艺术 记录(一)

    模拟死锁 package com.gjjun.concurrent; /** * 模拟死锁,来源于<Java并发编程的艺术> * @Author gjjun * @Create 2018/ ...

  5. Python第三方库之openpyxl(11)

    Python第三方库之openpyxl(11) Stock Charts(股票图) 在工作表上按特定顺序排列的列或行中的数据可以在股票图表中绘制.正如其名称所暗示的,股票图表通常被用来说明股价的波动. ...

  6. Webstrom卡顿问题解决

    1.设置node_modules 打开项目,新建node_modules空文件夹,然后右击选择Mark Directory as,选择Excluded. 2.设置ingore文件 files-> ...

  7. 通过日志动态查看正在执行的mysql语句

    通过日志动态查看正在执行的mysql语句 :tail -f /tmp/general_log.log

  8. 4A. Just a Hook

    4A. Just a Hook Time Limit: 2000ms Case Time Limit: 2000ms Memory Limit: 32768KB   64-bit integer IO ...

  9. eclipse中AXIS2发布过程

    Axis2服务端研究好几个小时,终于解决了 需要下载: 地址1: 可以从镜像站下载: 上海大学开源镜像站 地址2: 链接:从百度网盘下载; 密码:8nwu 其中第二个可以不用下: 解压后 将3,4解压 ...

  10. SQL Server中的@@ROWCOUNT

    SQL Server中@@ROWCOUNT返回受上一语句影响的行数,返回值类型为 int 整型. 如果行数大于 20 亿,则需要使用 ROWCOUNT_BIG. @@ROWCOUNT和@@ERROR变 ...