题目背景

有一天,小猫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. LeetCode 205 Isomorphic Strings(同构的字符串)(string、vector、map)(*)

    翻译 给定两个字符串s和t,决定它们是否是同构的. 假设s中的元素被替换能够得到t,那么称这两个字符串是同构的. 在用一个字符串的元素替换还有一个字符串的元素的过程中.所有字符的顺序必须保留. 没有两 ...

  2. Testing Is the Engineering Rigor of Software Development

    Testing Is the Engineering Rigor of Software Development Neal Ford DEVELOPERS LOVE TO USE TORTURED M ...

  3. 第十六周 项目三-max带来的冲突

    分析以下程序出现的编译错误,给出解决的方案. #include<iostream> using namespace std; //定义函数模板 template<class T> ...

  4. React学习之常用概念

    看见一篇不错的文章转载,文章源地址:https://blog.csdn.net/zwp438123895/article/details/69374940 一.  State和 Props state ...

  5. ppycharm设置解释器版本号码

    在pycharm中点击File,之后在弹出的窗口中输入Project Interpreter,点击之后就可以看到自己的解释器版本是多少了,也可以随意选择想要用的解释器版本号码:

  6. 制作一个塔防游戏 Cocos2d-x 2.1.4 (一)

    在这篇文章,将会学习到怎样制作一个塔防游戏.在这其中,学习怎样在设定的时间内出现一波波的敌人,使这些敌人沿着指定的路点前进.怎样在地图上指定的位置创建炮塔.怎样使炮塔射击敌人,怎样可视化调试路点和炮塔 ...

  7. 隐私问题成O2O绊脚石,加强行业监管迫在眉睫

        这年头,O2O的发展越来越给力了.因为O2O能充分结合互联网经济的线上优势和传统经济的线下优势,因此,传统商户纷纷借助O2O来开展业务,取得了不俗的成绩.只是,在移动互联网越来越"开 ...

  8. springboot中tomcat找不到jsp页面【转载】

    这个原理还没搞明白,只知道是内嵌的tomcat找jsp时默认不读取resources目录,但是具体的默认读取的是哪个目录,打了一下午断点我也没找到.... 修改方式,添加配置修改tomcat的读取目录 ...

  9. 基于live555实现的跨平台高性能RTSPServer流媒体服务器EasyIPCamera

    本文转自EasyDarwin团队成员kim的博客:http://blog.csdn.net/jinlong0603/article/details/52366412 简介 EasyIPCamera是由 ...

  10. GO 入门(一)

    1.下载安装go环境          https://golang.org/dl/ 2.检查环境变量配置情况,安装过程中会自动配置:GOROOT    和    Path 3.建立go工作区,并配置 ...