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; ...
随机推荐
- php冒泡排序实现方法,传入几个数字排序后 输出实战例子
php冒泡排序实现方法,传入几个数字排序后 输出实战例子 算法和数据结构是一个编程工作人员的内功.四种入门级排序算法: 冒泡排序.选择排序.插入排序.快速排序. 一.冒泡排序 原理:对一组数据,比较相 ...
- Git从远程仓库里拉取一条本地不存在的分支方法
Git从远程仓库里拉取一条本地不存在的分支方法 从远程仓库里拉取一条本地不存在的分支时,进入到对应目录先执行git fetch然后再执行git checkout -b 本地分支名 origin/远程分 ...
- web3.js编译Solidity,发布,调用全部流程(手把手教程)
web3.js编译Solidity,发布,调用全部流程(手把手教程) 下面教程是打算在尽量牵涉可能少的以太坊的相关工具,主要使用web3.js这个以太坊提供的工具包,来完成合约的编译,发布,合约方法调 ...
- GUI相应鼠标事件
function varargout = GUI18(varargin) % GUI18 MATLAB code for GUI18.fig % GUI18, by itself, creates a ...
- STM32硬件IIC (转)
源: STM32硬件IIC
- js通过DOM改变html和css
1.改变html输出流,通过document.write() 直接向 HTML 输出流写内容 <body> <p>段落</p> <script> doc ...
- PyCharm‘s Project Deployment
当在本地写完项目,部署到服务器上调试的时候,难免会碰到代码的修修改改,但由于项目在服务器上,修改起来相对麻烦.各路大神或许有自己的方法去解决.这篇博客演示利用PyCharm的Deployment功能, ...
- P3809 【模板】后缀排序
P3809 [模板]后缀排序 从这学的 后缀数组sa[i]就表示排名为i的后缀的起始位置 x[i]是第i个元素的第一关键字 y[i]表示第二关键字排名为i的数,在第一关键字中的位置 #include& ...
- 八数码问题 Eight Digital Problem
八数码问题 利用启发式搜索,找出以下问题的最优解. #include <iostream> #include <vector> #include <algorithm&g ...
- Linux启动报:UNEXPECTED INCONSISTENCY: RUN fsck MANUALLY问题解决
现象: 在此界面输入下root的密码.会进入到修复模式 在修复模式下,输入命令fsck –y /dev/mapper/vg_swnode1-lv_root 这个后面跟的路径就是你上面提示出错的那个路 ...