【BZOJ2809】【splay启发式合并】dispatching
Description
Input
Output
Sample Input
0 3 3
1 3 5
2 2 2
1 2 4
2 3 1
Sample Output
HINT
如果我们选择编号为 1的忍者作为管理者并且派遣第三个和第四个忍者,薪水总和为 4,没有超过总预算 4。因为派遣了 2 个忍者并且管理者的领导力为 3,
用户的满意度为 2 ,是可以得到的用户满意度的最大值。
Source
【分析】
什么启发式合并。叫得这么高端...不就是一个个插进去吗....
记得要用longlong
发现了一个很严重的问题,昨天的splay里面有问题。。
还是指针的问题....如果没有用引用的话就要返回,否则的话值不会变,貌似这个问题只有在以大小作为排序标准的情况下才会出现?
因为好像splay处理序列的时候一般是不需要根据大小排序的,所以一直没有发现....还好发现了,不然省选出现这个问题就跪了啊!!
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
#include <utility>
#include <iomanip>
#include <string>
#include <cmath>
#include <queue>
#include <assert.h>
#include <map>
#include <ctime>
#include <cstdlib>
#include <stack>
#define LOCAL
const int MAXN = + ;
const int INF = ;
const int SIZE = ;
const int maxnode = 0x7fffffff + ;
using namespace std;
vector<long long>G[MAXN];
stack<long long>S;
long long n;
long long b[MAXN];
long long c[MAXN], l[MAXN], m; struct SPLAY{
struct Node{
long long size;
long long val, sum;
Node *parent, *ch[]; long long cmp(){
if (parent->ch[] == this) return ;
else return ;
}
}*nil, _nil, mem[MAXN], *root[MAXN];
long long tot, pos;//pos表示当前根是哪一个 void update(Node *&t){
if (t == nil) return;
t->size = ;
t->size += t->ch[]->size + t->ch[]->size;
t->sum = t->val;
t->sum += t->ch[]->sum + t->ch[]->sum;
return;
}
void init(){
//循环哨兵
nil = &_nil;
_nil.val = _nil.size =_nil.sum = ;
_nil.parent = _nil.ch[] = _nil.ch[] = nil; tot = ;
//没有根就只能加一点特判断了
}
Node *NEW(long long val){
Node *p = &mem[tot++];
p->size = ;
p->val = p->sum = val;
p->parent = p->ch[] = p->ch[] = nil;
return p;
}
//旋转,d代表1右旋
void Rotate(Node *t, long long d){
Node *p = t->parent;
t = p->ch[d ^ ];
p->ch[d ^ ] = t->ch[d];
if (t->ch[d] != nil) t->ch[d]->parent = p;
t->ch[d] = p;
t->parent = p->parent;
//注意不是引用
if (t->parent != nil){
if (t->parent->ch[] == p) t->parent->ch[] = t;
else t->parent->ch[] = t;
}
p->parent = t;
if (t->parent == nil) root[pos] = t;
update(p);
update(t);
}
//没标记就是好TAT
Node* splay(Node *x, Node *y){
while (x->parent != y){
if (x->parent->parent == y){
Rotate(x, x->cmp() ^ );
break;
}else{
Rotate(x->parent, x->parent->cmp() ^ );
Rotate(x, x->cmp() ^ );
}
update(x);
}
update(x);
return x;
}
void insert(Node *&t, long long val){
if (t == nil){
t = NEW(val);
return;
}
Node *x = t;
Node *y = t;
while (){
long long d = (val >= x->val);
if (x->ch[d] == nil){
x->ch[d] = NEW(val);
x->ch[d]->parent = x;
//update(x);
t = splay(x->ch[d], nil);
return;
}else {x = x->ch[d];}
}
return;//不用update
}
void push(Node *&t){
if ( t == nil) return;
push(t->ch[]);
S.push(t->val);
push(t->ch[]);
}
//感动天地没有find!
Node* merge(Node *a, Node *b, long long pa, long long pb){
if (a == nil) return b;
else if (b == nil) return a;
//注意是将b插入a,为了启发式合并要判断大小
if (a->size < b->size){
//swap(root[pa], root[pb]);
swap(a, b);
}
push(b);//把p推到栈里面
while (!S.empty()){
insert(a, S.top());
S.pop();
}
//delete b;//可以删掉吧....
return a;
} //表示在Node*t中sum比m小
long long get(Node *t, long long val){
Node *x = t;
long long cnt = ;
while (){
if (x == nil) break;
if (val >= x->sum) {cnt += x->size; break;}//一次性全部拿完,包括子树
//能往左走当然尽量往左
long long tmp = (x->ch[]->sum);
//拿完左子树去右边拿
if (val >= (tmp + x->val)) {cnt += x->ch[]->size + ; val -= tmp + x->val; x = x->ch[];}
else x = x->ch[];//往左边拿
}
return cnt;
}
void work(){
init();
while (!S.empty()) S.pop();
long long Ans = ;
for (long long i = n; i >= ; i--){
if (G[i].size() == ){//叶子节点
root[i] = NEW(c[i]);
if (c[i] <= m) Ans = max(Ans, l[i]);
continue;
}
if (i == ){
//prlong long(root[8]);
//printf("\n\n\n");
}
root[i] = nil;//枚举每个管理者
pos = i;
insert(root[i], c[i]);
for (long long j = ; j < G[i].size(); j++){
long long v = G[i][j];
root[i] = merge(root[i], root[G[i][j]], i, v);
if (i == ){
// prlong long(root[3]);
//printf("\n\n\n");
}
}
//printf("%d\n", tot);
//if ((get(root[i], m) * l[i]) == 12)
//printf("");
if (i == ){
//printf("%d", root[3]->size);
//prlong long(root[8]);
}
Ans = max(Ans, get(root[i], m) * l[i]);
}
/*pos = n;
insert(root[n], 10);
insert(root[n], 1);*/
printf("%lld\n", Ans);
//printf("%d", tot);
}
/*void print(Node *t){
if (t == nil) return ;
prlong long(t->ch[0]);
printf("%lld %lld\n", t->val, t->parent->val);
prlong long(t->ch[1]);
}*/
void debug(){
init();
Node *p = NEW();
insert(p, );
printf("%lld", p->val);
}
}A; void read(){
//memest
long long sum = ;
scanf("%lld%lld", &n, &m);//m为薪水总预算
for (long long i = ; i <= n; i++){
//分别代表上级薪水领导力
scanf("%lld%lld%lld", &b[i], &c[i], &l[i]);
G[b[i]].push_back(i);
//sum += c[i];
//printf("%d %lld %d\n", b[i], c[i], (2568 / 428));
}
//第3个有6个
//printf("%d\n", m);
} int main(){ read();
A.work();
//A.debug();
return ;
}
【BZOJ2809】【splay启发式合并】dispatching的更多相关文章
- 【BZOJ-2809】dispatching派遣 Splay + 启发式合并
2809: [Apio2012]dispatching Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 2334 Solved: 1192[Submi ...
- 【BZOJ-2733】永无乡 Splay+启发式合并
2733: [HNOI2012]永无乡 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 2048 Solved: 1078[Submit][Statu ...
- BZOJ2733 永无乡【splay启发式合并】
本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/ ...
- BZOJ 2733: [HNOI2012]永无乡 [splay启发式合并]
2733: [HNOI2012]永无乡 题意:加边,询问一个连通块中k小值 终于写了一下splay启发式合并 本题直接splay上一个节点对应图上一个点就可以了 并查集维护连通性 合并的时候,把siz ...
- bzoj2733: [HNOI2012]永无乡(splay+启发式合并/线段树合并)
这题之前写过线段树合并,今天复习Splay的时候想起这题,打算写一次Splay+启发式合并. 好爽!!! 写了长长的代码(其实也不长),只凭着下午的一点记忆(没背板子...),调了好久好久,过了样例, ...
- 【BZOJ2733】永无乡[HNOI2012](splay启发式合并or线段树合并)
题目大意:给你一些点,修改是在在两个点之间连一条无向边,查询时求某个点能走到的点中重要度第k大的点.题目中给定的是每个节点的排名,所以实际上是求第k小:题目求的是编号,不是重要度的排名.我一开始差点被 ...
- 算法复习——splay+启发式合并(bzoj2733-永无乡)
题目: Description 永无乡包含 n 座岛,编号从 1 到 n,每座岛都有自己的独一无二的重要度,按照重要度可 以将这 n 座岛排名,名次用 1 到 n 来表示.某些岛之间由巨大的桥连接,通 ...
- 【BZOJ 2733】【HNOI 2012】永无乡 Splay启发式合并
启发式合并而已啦,, 调试时发现的错误点:insert后没有splay,把要拆开的树的点插入另一个树时没有把ch[2]和fa设为null,找第k大时没有先减k,,, 都是常犯的错误,比赛时再这么粗心就 ...
- 【洛谷P3224】永无乡 并查集+Splay启发式合并
题目大意:给定 N 个点的图,点有点权,初始有一些无向边,现在有 Q 个询问,每个询问支持动态增加一条无向边连接两个不连通的点和查询第 X 个点所在的联通块中权值第 K 大的是哪个点. 题解:学会了平 ...
随机推荐
- Linux Shell编程(12)——操作符
赋值变量赋值初始化或改变一个变量的值=通用的变量赋值操作符,可以用于数值和字符串的赋值 1 var=27 2 category=minerals # "="字符后面不能加 ...
- (转载)linux中shell变量
(转载)http://blog.csdn.net/zahuopuboss/article/details/8633891 为使shell编程更有效,系统提供了一些shell变量.shell变量可以保存 ...
- pm grant 命令
CustomLocale.apk所需要的权限"android.permission.CHANGE_CONFIGURATION"自Android 4.2,4.2.2起系统定义为and ...
- 在Windows Server 2012 上安装Exchange 2013 服务器
前文:http://www.cnblogs.com/Liangw/archive/2011/09/19/2559944.html 安装准备: 1.加入一个存在的域(?如何建立一个域) 2.登录Wind ...
- Sicily1020-大数求余算法及优化
Github最终优化代码: https://github.com/laiy/Datastructure-Algorithm/blob/master/sicily/1020.c 题目如下: 1020. ...
- javascript的几个问题
基础 1. 可选的分号 只有在缺少了分号就无法正确解析代码的时候,javascript,才会在一行的最后自动添加; a = 3 //自动填充 b = 4; var a a = 3 console.lo ...
- 广州Uber优步司机奖励政策(1月25日~1月31日)
滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...
- UVa10886 Standard Deviation
留坑(p.345) 这是什么意思 暴力? 然而那些有两个人跑的那么快是为什么?(有个人竟然是陈锋...)
- mysql 主从同步配置
1 环境 mac air 主机做 主库,使用的是XAMPP自带的mysql 版本为 5.6.21, for osx10.6 (x86_64) 虚拟机mysql 做从库 版本为 5.5.38, fo ...
- HTML5 File api 实现断点续传
目前市场上大多数的网站的断点上传都是需要安装浏览器插件的,本文就针对高级浏览器的环境下,通过HTML5 File api实现断点上传进行说明 一.实现文件多选 HTML5的<input>新 ...