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(左偏树)的更多相关文章

  1. HDU 5575 Discover Water Tank 并查集 树形DP

    题意: 有一个水槽,边界的两块板是无穷高的,中间有n-1块隔板(有高度),现有一些条件(i,y,k),表示从左到右数的第i列中,在高度为(y+0.5)的地方是否有水(有水:k = 1),问最多能同时满 ...

  2. HDU 1512 Monkey King(左偏树+并查集)

    [题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=1512 [题目大意] 现在有 一群互不认识的猴子,每个猴子有一个能力值,每次选择两个猴子,挑出他们所 ...

  3. HDU 5818 Joint Stacks(左偏树)

    [题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=5818 [题目大意] 给出两个栈A B(初始时为空),有三种操作: push.pop.merge. ...

  4. HDU 1512 Monkey King(左偏树模板题)

    http://acm.hdu.edu.cn/showproblem.php?pid=1512 题意: 有n只猴子,每只猴子一开始有个力量值,并且互相不认识,现有每次有两只猴子要决斗,如果认识,就不打了 ...

  5. HDU 1512 Monkey King(左偏树)

    Description Once in a forest, there lived N aggressive monkeys. At the beginning, they each does thi ...

  6. hdu 1512 Monkey King 左偏树

    题目链接:HDU - 1512 Once in a forest, there lived N aggressive monkeys. At the beginning, they each does ...

  7. hdu 1512 Monkey King —— 左偏树

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=1512 很简单的左偏树: 但突然对 rt 的关系感到混乱,改了半天才弄对: 注意是多组数据! #includ ...

  8. HDU 1512 Monkey King (左偏树+并查集)

    题意:在一个森林里住着N(N<=10000)只猴子.在一开始,他们是互不认识的.但是随着时间的推移,猴子们少不了争斗,但那只会发生在互不认识 (认识具有传递性)的两只猴子之间.争斗时,两只猴子都 ...

  9. HDU 1512 左偏树+并查集

    思路: 左偏树里面掺了一些并查集的应用 这里放一份左偏树的代码模板 重点就是merge函数了-- int merge(int k1,int k2){ if(!k1||!k2)return k1+k2; ...

随机推荐

  1. 转:【专题八】P2P编程

    引言: 前面的介绍专题中有朋友向我留言说介绍下关于P2P相关的内容的,首先本人对于C#网络编程也不是什么大牛,因为能力的关系,也只能把自己的一些学习过程和自己的一些学习过程中的理解和大家分享下的,下面 ...

  2. 【JavaScript 6连载】五、继承的概念

    <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...

  3. I2S接口介绍

    I2S接口介绍一.I2S协议介绍 I2S协议作为音频数据传输协议,由Philips制定.该协议由三条数据线组成:1.SCLK:串行时钟,频率= 2 * 采样频率 * 采样位数.2.WS:字段(声道)选 ...

  4. websocket 群聊单聊

    websocket 介绍 介绍引自 https://segmentfault.com/a/1190000012709475 群聊 from flask import Flask, request, r ...

  5. 和風いろはちゃんイージー / Iroha and Haiku (ABC Edition) (水水)

    题目链接:http://abc042.contest.atcoder.jp/tasks/abc042_a Time limit : 2sec / Memory limit : 256MB Score ...

  6. 怎样从外网访问内网Django?

    本地安装了一个Django,只能在局域网内访问,怎样从外网也能访问到本地的Django呢?本文将介绍具体的实现步骤. 准备工作 安装并启动Django 默认安装的Django端口是8000. 实现步骤 ...

  7. 查看gc的次数

    1,查找出程序进程id # 这里输出tomcat的进程id echo `ps -ef|grep tomcat|grep -v 'grep'|awk '{print $2'}` 2,查看gc的次数 js ...

  8. Eclipse Luna在线安装Maven时报错:Java heap space

    问题描述: 在线安装Maven插件时发生了:Java heap space 问题截图:

  9. kivy __init__() got an unexpected keyword argument '__no_builder' Kivy

    from kivy.lang.builder import Builder from kivy.app import App, runTouchApp from kivy.uix.boxlayout ...

  10. 用到临时表空间的几种SQL

    用到临时表空间的几种SQL CREATE INDEX SELECT ... ORDER BY SELECT DISTINCT ... SELECT ... GROUP BY SELECT ... UN ...