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; ...
随机推荐
- 常见的原生javascript DOM操作
1.创建元素 创建元素:document.createElement() 使用document.createElement()可以创建新元素.这个方法只接受一个参数,即要创建元素的标签名.这个标签名在 ...
- 底层代码创建GUI
%底层代码创建GUI hf = figure(... 'Units','Normalized',... 'Color','w',... 'Position',[0.1 0.1 0.8 0.8]); h ...
- 今日总结(linux和plsql)
#case ...when语句(根据字段不同值显示不同结果) ##1)case ...when语句的使用方法一: 语法格式: case column_name when value1 then res ...
- Failed to load ApplicationContext
java.lang.IllegalStateException: Failed to load ApplicationContext at org.springframework.test.conte ...
- 获取其他线程的数据用 queue, 多进程Q
获取其他线程的数据用 queue, 多进程Q
- direct加载之ora-39782一例
近日,我们有个环境在数据加载到oracle的时候出现ora-39782异常,版本是11.2.经google,几乎没有什么先例,因为我们是使用oci直接写的,可见现在还使用oci接口并不多,也或者我们的 ...
- C#.Net环境下的缓存技术
转载:https://www.cnblogs.com/lvjy-net/p/8297679.html 一.缓存技术本节将介绍以下技术: 使用Asp.Net缓存: 使用Remoting Singleto ...
- 【题解】Luogu P4979 矿洞:坍塌
原题传送门:P4979 矿洞:坍塌 这是某场膜你赛的题,最后我一百零几分rank三十几滚粗 这是我唯一ac的一题 这题比较简单qaq 前置芝士:珂朵莉树 窝博客里对珂朵莉树的介绍 没什么好说的自己看看 ...
- numpy 学习笔记
numpy 学习笔记 导入 numpy 包 import numpy as np 声明 ndarray 的几种方法 方法一,从list中创建 l = [[1,2,3], [4,5,6], [7,8,9 ...
- http 请求头大小写的问题
如果是默认消息头名称,消息头格式已经固定,即便输入的大小写有误,也会给你翻译成默认的写法,如果自己定义的,会自动给你翻译成小写,所以传参数的名称都用小写字母即可,否则可能取不到值,比如encrypte ...