题目背景

有一天,小猫rainbow和freda来到了湘西张家界的天门山玉蟾宫,玉蟾宫宫主蓝兔盛情地款待了它们,并赐予它们一片土地。

题目描述

这片土地被分成N*M个格子,每个格子里写着'R'或者'F',R代表这块土地被赐予了rainbow,F代表这块土地被赐予了freda。

现在freda要在这里卖萌。。。它要找一块矩形土地,要求这片土地都标着'F'并且面积最大。

但是rainbow和freda的OI水平都弱爆了,找不出这块土地,而蓝兔也想看freda卖萌(她显然是不会编程的……),所以它们决定,如果你找到的土地面积为S,它们每人给你S两银子。

输入输出格式

输入格式:

第一行两个整数N,M,表示矩形土地有N行M列。

接下来N行,每行M个用空格隔开的字符'F'或'R',描述了矩形土地。

输出格式:

输出一个整数,表示你能得到多少银子,即(3*最大'F'矩形土地面积)的值。

输入输出样例

输入样例#1:
复制

5 6
R F F F F F
F F F F F F
R R R F F F
F F F F F F
F F F F F F
输出样例#1: 复制

45

说明

对于50%的数据,1<=N,M<=200

对于100%的数据,1<=N,M<=1000

题解

这是来自我校学长(祖传)的并查集做法

首先从上到下枚举每一行(分割线)。

在当前行,把它以上的F染色,那么F会构成这样的图案↓

每一列在这条分割线以上有多少连续的F,可以在每次下移分割线时顺便用O(m)扫一遍维护。(如果这一格为F,那么连续F为之前这列的连续F加1;否则为0)

然后我们按照每一列的F高度排序,每次把F最高的取出来。

如果它左边一列被取过了,我们就把当前列和它左边一列并起来;如果右边一列被取过,就把这一列和右边一列并起来。

最后询问一下这一列的祖先有多少个子节点,也就是这一列以它的高度往左右最多能扩展的宽度。

原理:在当前列之前被并入这个祖先的列的长度一定大于等于当前列的长度,并且这些列互相相邻。

然后当前列的高度,乘上它往左右最多能扩展的宽度,就是取这一列,且高度等于这一列的最大矩形面积了。(就算还有相同高度的没有处理,之后做那一列的时候也会得到最优解)

实现的时候只需要把两个需要合并的列的祖先节点$fa[v]=u,siz[u]+=siz[v]$就可以了,因为只有祖先节点的siz是有意义的。

因为懒所以直接用了优先队列,并查集只路径压缩也是$O(mlogm)$的时间,总复杂度$O(nmlogm)$

 /*
qwerta
P4147 玉蟾宫
Accepted
100
代码 C++,1.14KB
提交时间 2018-10-14 22:07:46
耗时/内存
1724ms, 916KB
*/
#include<iostream>
#include<cstdio>
#include<queue>
using namespace std;
int s[];//记录每列往上F的高度
int fa[],siz[];//并查集
bool sf[];//标记每一列是否被用过
struct emm{
int nod,v;
};
struct cmp{
bool operator()(emm qaq,emm qwq){
return qaq.v<qwq.v;
}
};//重载()运算符(用来给优先队列排序
priority_queue<emm,vector<emm>,cmp>q;
int fifa(int x)
{
if(fa[x]==x)return x;
return fa[x]=fifa(fa[x]);
}
void con(int x,int y)//把x列和y列并起来
{
int u=fifa(x),v=fifa(y);
fa[v]=u;
siz[u]+=siz[v];
return;
}
int main()
{
//freopen("a.in","r",stdin);
ios::sync_with_stdio(false);
cin.tie(false),cout.tie(false);//关闭同步流(让cin变快
int n,m;
cin>>n>>m;
int ans=;
for(int c=;c<=n;++c)//从上往下移分割线
{
for(int i=;i<=m;++i)
{
char ch;
cin>>ch;
if(ch=='F'){s[i]++;q.push((emm){i,s[i]});}
else s[i]=;
}
for(int i=;i<=m;++i)
fa[i]=i,siz[i]=,sf[i]=;//初始化
while(!q.empty())
{
int i=q.top().nod,x=q.top().v;q.pop();
sf[i]=;//标记这一列取过了
if(sf[i-])con(i-,i);//如果左边取过了就并起来
if(sf[i+])con(i,i+);//如果右边取过了就并起来
int fi=fifa(i);//找祖先节点
ans=max(ans,siz[fi]*x);
}
}
cout<<ans*;//输出最大矩形面积*3
return ;
}

「LuoguP4147」 玉蟾宫(并查集的更多相关文章

  1. 「Poetize4」玉蟾宫

    描述 Description 这片土地被分成N*M个格子,每个格子里写着'R'或者'F',R代表这块土地被赐予了rainbow,F代表这块土地被赐予了freda.现在freda要在这里卖萌...它要找 ...

  2. 「LOJ#10015」「一本通 1.2 练习 2」扩散(并查集

    题目描述 一个点每过一个单位时间就会向 444 个方向扩散一个距离,如图所示:两个点 a .b 连通,记作 e(a,b),当且仅当 a .b的扩散区域有公共部分.连通块的定义是块内的任意两个点 u.v ...

  3. [loj6038]「雅礼集训 2017 Day5」远行 lct+并查集

    给你 n 个点,支持 m 次操作,每次为以下两种:连一条边,保证连完后是一棵树/森林:询问一个点能到达的最远的点与该点的距离.强制在线. n≤3×10^5 n≤3×10^5 ,m≤5×10^5 m≤5 ...

  4. Comet OJ - Contest #13 「佛御石之钵 -不碎的意志-」(困难版) 并查集

    题意 给一个$ n \times m$ 的网格,每个格子里有一个数字,非 \(0\) 即 \(1\),行从上往下依次编号为 \(1, 2, \cdots, n\),列从左往右依次编号为 \(1, 2, ...

  5. 「luogu3402」【模板】可持久化并查集

    「luogu3402」[模板]可持久化并查集 传送门 我们可以用一个可持久化数组来存每个节点的父亲. 单点信息更新和查询就用主席树多花 一个 \(\log\) 的代价来搞. 然后考虑如何合并两个点. ...

  6. 【loj6038】「雅礼集训 2017 Day5」远行 树的直径+并查集+LCT

    题目描述 给你 $n$ 个点,支持 $m$ 次操作,每次为以下两种:连一条边,保证连完后是一棵树/森林:询问一个点能到达的最远的点与该点的距离.强制在线. $n\le 3\times 10^5$ ,$ ...

  7. 初涉「带权并查集」&&bzoj3376: [Usaco2004 Open]Cube Stacking 方块游戏

    算是挺基础的东西 Description     约翰和贝茜在玩一个方块游戏.编号为1到n的n(1≤n≤30000)个方块正放在地上.每个构成一个立方柱.    游戏开始后,约翰会给贝茜发出P(1≤P ...

  8. 概述「并查集补集转化」模型&&luoguP1330 封锁阳光大学

    奇妙的模型转化以及并查集思想 模型概述 有图$G=(V,E)$,初始所有点为白色,现在要将其中一些点染为黑色,要求染色后满足:$∀(u,v)∈E$,$∃col_u!=col_v$.求最小染色点数. 题 ...

  9. 「CF319E」Ping-Pong「线段树」「并查集」

    题意 规定区间\((a,b)\)到区间\((c,d)\)有边当且仅当\(c<a<d\)或\(c<b<d\). 起初区间集合为空.有\(n\)(\(n\leq 10^5\))次操 ...

随机推荐

  1. BEGINNING SHAREPOINT&#174; 2013 DEVELOPMENT 第2章节--SharePoint 2013 App 模型概览 SharePoint 2013 App 模型

    BEGINNING SHAREPOINT® 2013 DEVELOPMENT 第2章节--SharePoint 2013 App 模型概览 SharePoint 2013 App 模型 你能够通过两个 ...

  2. 表现层 JSP 页面实现

    一.实验介绍 1.1 实验内容 本节课程主要利用 easyUI 实现系统的前端页面. 1.2 实验知识点 easyUI JavaScript html 1.3 实验环境 JDK1.8 Eclipse ...

  3. display:flex不兼容Android、Safari低版本的解决方案 【flex布局】

    引自 http://www.cnblogs.com/shimily/articles/7943370.html <!DOCTYPE html> <html lang="en ...

  4. favico是针对网页图标内容更改

    favico.js源码 (function () { var Favico = function (opt) { "use strict"; opt = opt ? opt : { ...

  5. javascript 转义函数

    // 字符转义 html2Escape(sHtml) { return sHtml.replace(/[<>&"]/g, function(c) { return { ' ...

  6. python(19)- 列表生成式和生成器表达式练习Ⅰ

    列表表达式 程序一: 常规写法: egg_list=[] for i in range(100): egg_list.append('egg%s' %i) print(egg_list) 列表表达式写 ...

  7. 读取配置文件(configparser,.ini文件)

    使用configparser来读取配置信息config.ini 读取的信息(config.ini)如下: [baseconf]host=127.0.0.1port=3306user=rootpassw ...

  8. speechSynthesis,TTS语音合成。

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

  9. 解析java.math.BigInteger类——构造函数

    最早由于做作业,结识了java的BigInrger类.读着读着,越来越觉得有趣.后来作业做完,也不忍丢下它,索性把全部代码研究一遍. 开始的时候,一个上午时间最多读懂2个方法.但是还是有滋有味的坚持了 ...

  10. 辛星浅析html5中的role属性

    我们使用role属性告诉辅助设备.这个元素所扮演的角色.比方点击的按钮,我们通常就使用role="button",会让这个元素可点击. 可是它很多其它的是用来增强语义性,当现有的h ...