Wannafly挑战赛2 C.Butterfly(线段树优化枚举)
题目链接 C.Butterfly
令$fd[i][j]$为以$s[i][j]$为起点开始往下走最大连续的‘X’个数
令$fl[i][j]$为以$s[i][j]$为起点开始往左下走最大连续的‘X’个数
令$fr[i][j]$为以$s[i][j]$为起点开始往左下走最大连续的‘X’个数
令$a[i][j] = min(fd[i][j], fl[i][j])$, $b[i][j] = min(fd[i][j], fr[i][j])$
对于每一个$(i, j)$, 我们要找到$(i, k)$
使得$k$最大,并且$k >= j$, $k - j + 1 <= min(a[i][j], b[i][k])$
$k - j + 1$必须为奇数
把所有条件整理出来就是
$k - j + 1 <= a[i][j]$
$k - j + 1 <= b[i][k]$
移项得到
$k <= a[i][j] + j - 1$
$k - b[i][k] + 1 <= j$
所以我们可以对$k - b[i][k] + 1$排序,当$j$从$1$扫到$m$的时候每一次确保所有满足$k - b[i][k] + 1$的$k$都已经被添加到线段树中
那么我们在$[j, a[i][j] + j - 1]$这段区间里面查找最大值(也就是符合条件的最大的$k$)更新答案即可。
注意分奇偶讨论
#include <bits/stdc++.h> using namespace std; #define rep(i, a, b) for (int i(a); i <= (b); ++i)
#define dec(i, a, b) for (int i(a); i >= (b); --i)
#define fi first
#define se second
#define MP make_pair
#define lson i << 1, L, mid
#define rson i << 1 | 1, mid + 1, R typedef pair <int, int> PII; const int N = 2010; char s[N][N];
int fd[N][N], fl[N][N], fr[N][N], a[N][N], b[N][N];
int n, m, now;
int t[N << 4];
int cnt, mx, ans = 0; PII c[N]; inline void pushup(int i){ t[i] = max(t[i << 1], t[i << 1 | 1]); } void update(int i, int L, int R, int x, int val){
if (L == R && L == x){
t[i] = max(t[i], val);
return;
} int mid = (L + R) >> 1;
if (x <= mid) update(lson, x, val);
else update(rson, x, val);
pushup(i);
} int query(int i, int L, int R, int l, int r){
if (l <= L && R <= r) return t[i];
int mid = (L + R) >> 1;
if (r <= mid) return query(lson, l, r);
else if (l > mid) return query(rson, l, r);
else return max(query(lson, l, r), query(rson, l, r));
} int main(){ scanf("%d%d", &n, &m);
rep(i, 1, n) scanf("%s", s[i] + 1);
dec(i, n, 1) rep(j, 1, m){
fd[i][j] = s[i][j] == 'X' ? fd[i + 1][j] + 1 : 0;
fl[i][j] = s[i][j] == 'X' ? fl[i + 1][j - 1] + 1 : 0;
fr[i][j] = s[i][j] == 'X' ? fr[i + 1][j + 1] + 1 : 0;
} rep(i, 1, n) rep(j, 1, m) a[i][j] = min(fd[i][j], fr[i][j]), b[i][j] = min(fd[i][j], fl[i][j]); mx = m << 1;
ans = 0; rep(i, 1, n){
cnt = 0;
for (int j = 1; j <= m; j += 2) if (b[i][j]) c[++cnt] = MP(j - b[i][j] + 1, j);
sort(c + 1, c + cnt + 1); memset(t, 0, sizeof t);
now = 0;
for (int j = 1; j <= m; j += 2){
if (!a[i][j]) continue;
while (now < cnt){
if (c[now + 1].fi <= j){
++now;
update(1, 1, mx, c[now].se, c[now].se);
if (now >= cnt) break;
}
else break;
} int et = query(1, 1, mx, j, a[i][j] + j - 1);
ans = max(ans, et - j + 1);
} cnt = 0;
for (int j = 2; j <= m; j += 2) if (b[i][j]) c[++cnt] = MP(j - b[i][j] + 1, j);
sort(c + 1, c + cnt + 1); memset(t, 0, sizeof t);
now = 0;
for (int j = 2; j <= m; j += 2){
if (!a[i][j]) continue;
while (now < cnt){
if (c[now + 1].fi <= j){
++now;
update(1, 1, mx, c[now].se, c[now].se);
if (now >= cnt) break;
}
else break;
} int et = query(1, 1, mx, j, a[i][j] + j - 1);
ans = max(ans, et - j + 1);
}
} printf("%d\n", ans);
return 0;
}
Wannafly挑战赛2 C.Butterfly(线段树优化枚举)的更多相关文章
- [USACO2005][POJ3171]Cleaning Shifts(DP+线段树优化)
题目:http://poj.org/problem?id=3171 题意:给你n个区间[a,b],每个区间都有一个费用c,要你用最小的费用覆盖区间[M,E] 分析:经典的区间覆盖问题,百度可以搜到这个 ...
- Weak Pair---hud5877大连网选(线段树优化+dfs)
题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=5877 题意:给你一颗树,有n个节点,每个节点都有一个权值v[i]:现在求有多少对(u,v ...
- CodeForces 558E(计数排序+线段树优化)
题意:一个长度为n的字符串(只包含26个小字母)有q次操作 对于每次操作 给一个区间 和k k为1把该区间的字符不降序排序 k为0把该区间的字符不升序排序 求q次操作后所得字符串 思路: 该题数据规模 ...
- HDU4719-Oh My Holy FFF(DP线段树优化)
Oh My Holy FFF Time Limit: 5000/2500 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others) T ...
- UOJ#77. A+B Problem [可持久化线段树优化建边 最小割]
UOJ#77. A+B Problem 题意:自己看 接触过线段树优化建图后思路不难想,细节要处理好 乱建图无果后想到最小割 白色和黑色只能选一个,割掉一个就行了 之前选白色必须额外割掉一个p[i], ...
- Codeforces 558E A Simple Task (计数排序&&线段树优化)
题目链接:http://codeforces.com/contest/558/problem/E E. A Simple Task time limit per test5 seconds memor ...
- 2019.03.09 codeforces833B. The Bakery(线段树优化dp)
传送门 线段树优化dpdpdp入门题. 要求把nnn个数分成kkk段,每段价值为里面不相同的数的个数,求所有段的价值之和最大值.n≤35000,k≤50n\le35000,k\le50n≤35000, ...
- Codeforces 1045. A. Last chance(网络流 + 线段树优化建边)
题意 给你 \(n\) 个武器,\(m\) 个敌人,问你最多消灭多少个敌人,并输出方案. 总共有三种武器. SQL 火箭 - 能消灭给你集合中的一个敌人 \(\sum |S| \le 100000\) ...
- bzoj千题计划311:bzoj5017: [Snoi2017]炸弹(线段树优化tarjan构图)
https://www.lydsy.com/JudgeOnline/problem.php?id=5017 暴力: 对于每一个炸弹,枚举所有的炸弹,看它爆炸能不能引爆那个炸弹 如果能,由这个炸弹向引爆 ...
随机推荐
- python numpy复制array
numpy快速复制array 前段时间想到一个算法,需要实现array的自我复制,直接上代码,两种复制方式, 整体复制 a=[[10,10,50,50],[10,10,40,50]] np.tile( ...
- python3与python2的编码问题
在讲这个问题之前,我们先说说unicode的工作原理.unicode包含了跟全球所有国家编码的映射关系,就是不管你用哪个国家的编码,unicode都能找到它在unicode中的编码.那么无论你用什么编 ...
- Do not pour out HDU - 5954 数学积分
题目:题目链接 思路:纯高等数学问题,不过不是很好积分,具体积分思路及过程参考大佬博客——https://blog.csdn.net/danliwoo/article/details/53002695 ...
- Phonegap环境配置和安装插件
一:安装好jdk(配置好环境变量) 二:安装好Android SDK(配置好环境变量path F:\Android\android-sdk-windows\platform-tools;F:\Andr ...
- c#利用反射实现对类中的常量进行取值和对应常量的注释
C#利用反射实现对类中的常量进行取值和对应常量的注释 项目示例:https://gitee.com/dhclly/IceDog.GenerateErrorCode 因为业务需要,项目中有大量的错误码, ...
- git仓库删除所有提交历史记录
stackoverflow原问题地址:http://stackoverflow.com/questions/13716658/how-to-delete-all-commit-history-in-g ...
- js各种继承方式和优缺点的介绍
js各种继承方式和优缺点的介绍 作者: default 参考网址2 写在前面 本文讲解JavaScript各种继承方式和优缺点. 注意: 跟<JavaScript深入之创建对象>一样,更像 ...
- day01_04.变量
变量的命名规则 变量名由字母小写a-z,大写A-Z,_下划线,数字0-9组成,php的变量名区分大小写;python的变量名也是区分大小写的 注意: PHP变量名必须以美元$符号开始; 变量名开头可以 ...
- python装饰器实现用户密码认证(简单初形)
import timecurrent_user={'user':None}def auth(engine = 'file'): def deco(func): #func=最初始的index和最初始的 ...
- Wannafly挑战赛9
链接:https://www.nowcoder.com/acm/contest/71/A来源:牛客网 找一找 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 262144K,其他语言5 ...