[bzoj5101][POI2018]Powódź_并查集
Powódź bzoj-5101 POI-2018
题目大意:在地面上有一个水箱,它的俯视图被划分成了$n$行$m$列个方格,相邻两个方格之间有一堵厚度可以忽略不计的墙,水箱与外界之间有一堵高度无穷大的墙,因此水不可能漏到外面。已知水箱内每个格子的高度都是$[0,H]$之间的整数,请统计有多少可能的水位情况。因为答案可能很大,请对$10^9+7$取模输出。两个情况不同当且仅当存在至少一个方格的水位在两个情况中不同。
注释:$1\le n\times m\le 10^5$,$1\le H\le 10^9$。
想法:神题一道。
不好想啊不好想
如果水位高于两个块之间的墙那么这两个块我们称之为连通,用并查集维护。
这样的话我们将墙墙们按照高度排序。
每次如果墙左右的两个联通块不连通的话就连一起。
假设$g_x$为祖先为$x$的联通块内部的答案。这个答案的是以联通块内的最后一次完成内部合并的墙墙高度最大值。
再维护$h_x$为该联通块内的那个高度。
$val[i]$为当前枚举的墙墙高度。(墙墙已经被排好序了。
所以更新后:$g_x=(g_x+val[i]-h_x)\times(g_y+val[i]-h_y)$。
最后我们再加上$H-h[find(1)]$即可。
Code:
#include <bits/stdc++.h>
#define M 1000010
#define N 500010
#define mod 1000000007
using namespace std;
int f[N],g[N],h[N],cnt;
struct Node {int x,y,val;}a[M]; inline bool cmp_val(const Node &a,const Node &b) {return a.val<b.val;}
inline char nc() {static char *p1,*p2,buf[100000]; return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;}
int rd() {int x=0; char c=nc(); while(!isdigit(c)) c=nc(); while(isdigit(c)) x=(x<<3)+(x<<1)+(c^48),c=nc(); return x;}
int find(int x) {return f[x]==x?x:f[x]=find(f[x]);}
inline bool merge(int x,int y)
{
x=find(x); y=find(y);
if(x==y) return true;
f[y]=x; return false;
}
inline void add(int x,int y,int z) {a[++cnt].x=x,a[cnt].y=y,a[cnt].val=z;}
int main()
{
int n=rd(),m=rd(),H=rd(); for(int i=1;i<=n;i++)
{
for(int j=1;j<=m-1;j++) {int x=rd(); add((i-1)*m+j,(i-1)*m+j+1,x);}
}
for(int i=1;i<=n-1;i++)
{
for(int j=1;j<=m;j++) {int x=rd(); add((i-1)*m+j,i*m+j,x);}
}
for(int i=1;i<=n;i++) for(int j=1;j<=m;j++)
{
f[(i-1)*m+j]=(i-1)*m+j;
g[(i-1)*m+j]=1;
}
sort(a+1,a+cnt+1,cmp_val);
for(int i=1;i<=cnt;i++)
{
if(!merge(a[i].x,a[i].y))
{
int x=find(a[i].x),y=find(a[i].y);
g[x]=1ll*(g[x]+a[i].val-h[x])*(g[y]+a[i].val-h[y])%mod;
h[x]=a[i].val;
}
}
printf("%d\n",(g[find(1)]+H-h[find(1)])%mod);
return 0;
}
小结:并查集的应用好题。
[bzoj5101][POI2018]Powódź_并查集的更多相关文章
- BZOJ_3362_[Usaco2004 Feb]Navigation Nightmare 导航噩梦_并查集
BZOJ_3362_[Usaco2004 Feb]Navigation Nightmare 导航噩梦_并查集 Description 农夫约翰有N(2≤N≤40000)个农场,标号1到N,M( ...
- BZOJ_2303_[Apio2011]方格染色 _并查集
BZOJ_2303_[Apio2011]方格染色 _并查集 Description Sam和他的妹妹Sara有一个包含n × m个方格的 表格.她们想要将其的每个方格都染成红色或蓝色. 出于个人喜好, ...
- BZOJ_1015_[JSOI2008]星球大战_并查集
BZOJ_1015_[JSOI2008]星球大战_并查集 题意:很久以前,在一个遥远的星系,一个黑暗的帝国靠着它的超级武器统治者整个星系.某一天,凭着一个偶然的 机遇,一支反抗军摧毁了帝国的超级武器, ...
- BZOJ_1998_[Hnoi2010]Fsk物品调度_并查集+置换
BZOJ_1998_[Hnoi2010]Fsk物品调度_并查集+置换 Description 现在找工作不容易,Lostmonkey费了好大劲才得到fsk公司基层流水线操作员的职位.流水线上有n个位置 ...
- BZOJ_2443_[Usaco2011 Open]奇数度数 _并查集+树形DP
BZOJ_2443_[Usaco2011 Open]奇数度数 _并查集. Description 奶牛们遭到了进攻!在他们的共和国里,有N(1 <= N <=50,000)个城市,由M(1 ...
- [Comet OJ - Contest #6 D][48D 2280]另一道树题_并查集
另一道树题 题目大意: 数据范围: 题解: 这个题第一眼能发现的是,我们的答案分成两种情况. 第一种是在非根节点汇合,第二种是在根节点汇合. 尝试枚举在第几回合结束,假设在第$i$回合结束的方案数为$ ...
- BZOJ_1015_星球大战_[JSOI2008]_(并查集)
描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1015 n 个点,被 m 条边相连.进行k次删点操作,问第一次操作前和每次操作后的集合数(直接或 ...
- BZOJ_1202_狡猾的商人_(并查集)
描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1202 n 个月的账单,共 m 组数据,每一组数据包括 x , y , t ,表示从 x 月到 ...
- POJ_1182_食物链_[NOI]_(并查集)
描述 http://poj.org/problem?id=1182 共A,B,C三种动物,A吃B,B吃C,C吃A.给出询问 q : t , x , y , 表示: x 与 y 是同类 ( t==1 ...
随机推荐
- JDK集合框架--ArrayList
ArrayList,从类名就可以看出来,这是由数组实现的List,即内部是用数组保存元素的有序集合.先看看主要的成员变量,比较简单: public class ArrayList<E> e ...
- AJPFX详解泛型中super和extends关键字
首先,我们定义两个类,A和B,并且假设B继承自A.下面的代码中,定义了几个静态泛型方法,这几个例子随便写的,并不是特别完善,我们主要考量编译失败的问题: Java代码 public class Ge ...
- absolute元素水平居中
原始(未居中): .con{ width:200px; height:200px; background:#ccc; position:relative; } .abs{ width:40px; he ...
- 一段js实现复制文本内容到剪切板
<script type="text/javascript"> function copyUrl2() { var Url2=document.getElementBy ...
- Sass的的使用一
sass -v 检测是否安装 Sass 成功 gem update sass 更新 Sass gem uninstall sass 删除/卸载 Sass 的编译有多种方法: 1.命令编译2.GUI工具 ...
- 通过SSDT HOOK实现进程保护和进程隐藏
---恢复内容开始--- 首先,我要说一件很重要的事,本人文采不好,如果哪里说的尴尬了,那你就尴尬着听吧...... SSDT HOOK最初貌似源于Rookit,但是Rookit之前有没有其他病毒使用 ...
- CREATE LANGUAGE - 定义一种新的过程语言
SYNOPSIS CREATE [ TRUSTED ] [ PROCEDURAL ] LANGUAGE name HANDLER call_handler [ VALIDATOR valfunctio ...
- windows sdk 设置窗体透明
#define WINVER 0x0501 #include <windows.h> /* Declare Windows procedure */ LRESULT CALLBACK Wi ...
- 循环冗余校验(CRC)算法入门
http://blog.csdn.net/liyuanbhu/article/details/7882789 前言 CRC校验(循环冗余校验)是数据通讯中最常采用的校验方式.在嵌入式软件开发中,经常要 ...
- Java A
4.在ORACLE大数据量下的分页解决方法.一般用截取ID方法,还有是三层嵌套方法. 答:一种分页方法 <% int i=1; int numPages=14; String pages = r ...