HDU 5575 Discover Water Tank(左偏树)
https://vjudge.net/problem/HDU-5575
题意:
有一个水箱,被n-1块板子分成了n个部分,板子的高度不尽相同。现在有m次探测,每次探测在第x部分的y+0.5高度处是否有水,回答0代表没水,1代表有水。现在要求出这m次探测最多有多少次是正确的。
思路:
挺难的一道题目吧。
一开始如果把水箱当成空的,那么所有的无水探测就都是真的,至于有水探测的话,接下来我们可以一点一点的加水,这就要求将有水探测排序。每个部分可能会有多个无水探测(比如在第1部分,它进高度为1、3、5的地方都进行无水探测),那么在被淹没的时候肯定最先淹没高度为1的地方。这样的话,对于每个部分都可以建立一个优先队列,每次弹出值最小的。但是这些部分还会因为淹没而变成一部分,这时候要将两个部分的优先队列合并起来,这样的话,就是一个左偏树了。
#include<iostream>
#include<cstdio>
#include<vector>
#include<cstring>
#include<algorithm>
using namespace std; typedef pair<int,int> pll;
const int INF = 0x3f3f3f3f;
const int maxn = 1e5 + ; int n,m,ans,tot;
int LH[maxn],RH[maxn],L[maxn],R[maxn];
int heap[maxn];
int ok[maxn],nok[maxn],p[maxn]; vector<pll> query; struct node
{
int l,r,dis,key;
}t[*maxn]; int initHeap(int x)
{
t[++tot].key = x;
t[tot].l = t[tot].r = t[tot].dis = ;
return tot;
} int merge(int x, int y)
{
if(x == ) return y;
if(y == ) return x;
if(t[x].key>t[y].key) swap(x,y);
t[x].r = merge(t[x].r,y);
if(t[t[x].l].dis < t[t[x].r].dis) swap(t[x].l,t[x].r);
if(t[x].r==) t[x].dis = ;
else t[x].dis = t[t[x].r].dis + ;
return x;
} int insert(int x, int y)
{
return merge(x,initHeap(y));
} int pop(int x)
{
return merge(t[x].l,t[x].r);
} int finds(int x)
{
return x==p[x]?x:p[x]=finds(p[x]);
} void unions(int x, int y)
{
x = finds(x);
y = finds(y);
if(x==y) return; p[y] = x;
if(x>y) //合并两个部分
{
LH[x] = LH[y];
L[x] = L[y];
}
else
{
RH[x] = RH[y];
R[x] = R[y];
} heap[x] = merge(heap[x],heap[y]); //合并两个部分的左偏树
ok[x] += ok[y];
nok[x] += nok[y];
} int main()
{
//freopen("in.txt","r",stdin);
int T;
scanf("%d",&T);
int kase = ;
while(T--)
{
query.clear();
memset(heap,,sizeof(heap)); scanf("%d%d",&n,&m);
LH[] = RH[n] = INF;
for(int i=;i<n;i++)
{
scanf("%d",&RH[i]);
LH[i+] = RH[i];
L[i] = i-; //i的左边
R[i] = i+; //i的右边
}
L[n]=n-;
ans = tot = ;
while(m--)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
if(z==)
{
if(heap[x]==) heap[x] = initHeap(y);
else heap[x] = insert(heap[x],y);
ans++;
}
else
{
query.push_back(make_pair(y,x));
}
}
sort(query.begin(),query.end());
for(int i=;i<=n;i++) ok[i]=nok[i]=;
for(int i=;i<=n;i++) p[i] = i;
for(int i=;i<query.size();i++)
{
int x = finds(query[i].second);
int y = query[i].first;
while(y>LH[x]) unions(x,L[x]); //向左溢出
while(y>RH[x]) unions(x,R[x]); //向右溢出
while(heap[x]!= && t[heap[x]].key<y)
{
heap[x] = pop(heap[x]);
nok[x]++;
}
ok[x]++; //当前进行的是真
if(ok[x]>=nok[x])
{
ans+=ok[x]-nok[x];
ok[x] = nok[x] = ;
}
}
printf("Case #%d: %d\n",++kase,ans);
}
return ;
}
HDU 5575 Discover Water Tank(左偏树)的更多相关文章
- HDU 5575 Discover Water Tank 并查集 树形DP
题意: 有一个水槽,边界的两块板是无穷高的,中间有n-1块隔板(有高度),现有一些条件(i,y,k),表示从左到右数的第i列中,在高度为(y+0.5)的地方是否有水(有水:k = 1),问最多能同时满 ...
- HDU 1512 Monkey King(左偏树+并查集)
[题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=1512 [题目大意] 现在有 一群互不认识的猴子,每个猴子有一个能力值,每次选择两个猴子,挑出他们所 ...
- HDU 5818 Joint Stacks(左偏树)
[题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=5818 [题目大意] 给出两个栈A B(初始时为空),有三种操作: push.pop.merge. ...
- HDU 1512 Monkey King(左偏树模板题)
http://acm.hdu.edu.cn/showproblem.php?pid=1512 题意: 有n只猴子,每只猴子一开始有个力量值,并且互相不认识,现有每次有两只猴子要决斗,如果认识,就不打了 ...
- HDU 1512 Monkey King(左偏树)
Description Once in a forest, there lived N aggressive monkeys. At the beginning, they each does thi ...
- hdu 1512 Monkey King 左偏树
题目链接:HDU - 1512 Once in a forest, there lived N aggressive monkeys. At the beginning, they each does ...
- hdu 1512 Monkey King —— 左偏树
题目:http://acm.hdu.edu.cn/showproblem.php?pid=1512 很简单的左偏树: 但突然对 rt 的关系感到混乱,改了半天才弄对: 注意是多组数据! #includ ...
- HDU 1512 Monkey King (左偏树+并查集)
题意:在一个森林里住着N(N<=10000)只猴子.在一开始,他们是互不认识的.但是随着时间的推移,猴子们少不了争斗,但那只会发生在互不认识 (认识具有传递性)的两只猴子之间.争斗时,两只猴子都 ...
- HDU 1512 左偏树+并查集
思路: 左偏树里面掺了一些并查集的应用 这里放一份左偏树的代码模板 重点就是merge函数了-- int merge(int k1,int k2){ if(!k1||!k2)return k1+k2; ...
随机推荐
- flask 使用宏渲染表单(包含错误信息)
在模板中渲染表单时,有大量的工作: 1.调用字段属性,获取<input>定义 2.调用对应的label属性,获取<label>定义 3.渲染错误消息 为了避免为每一个字段重复这 ...
- 100.容器List-ArrayList
package collection; import java.util.ArrayList; import java.util.Collection; import java.util.Date; ...
- Codeforce 814A - An abandoned sentiment from past (贪心)
A few years ago, Hitagi encountered a giant crab, who stole the whole of her body weight. Ever since ...
- [转载]Oracle数据库 sql%found,sql%notfound,sql%rowcount
sql%found,sql%notfound,sql%rowcount 在执行DML(insert,update,delete)语句时,可以用到以下三个隐式游标(游标是维护查询结果的内存中的一个区域, ...
- kali linux中文输入法
kali linux中文输入法 已经使用kali linux有一段时间来,越用越喜欢,真的奥! 最近又有宝宝问我kali linux的中文输入法,鉴于当初在坑里蹲了很长时间,还是记录一下吧! The ...
- MyEclipse 10.7(版本:eclipse 3.7.x-Indigo系列)安装PyDev 4.5.4插件
解压安装路径结构如截图所示: 安装后重启:
- MMU工作原理(转)
源: MMU工作原理
- apache编译安装php后需要注意以下配置
安装后, 编辑apache配置文件 vi /usr/local/apache2/conf/httpd.conf 可以看到 LoadModule php7_module modules/libphp7. ...
- JavaScript 条件判断算法综合实战
在赌场21点游戏中,玩家可以通过计算牌桌上已经发放的卡牌的高低值来让自己在游戏中保持优势,这就叫21点算法. 根据下面的表格,每张卡牌都分配了一个值.如果卡牌的值大于0,那么玩家应该追加赌注.反之,追 ...
- Codeforces Round #481 (Div. 3)题解
成功掉到灰,真的心太累了,orz!!!!,不是很懂那些国外大佬为什么每次都是20多分钟AK的,QAQ A. Remove Duplicates time limit per test 1 second ...