【BZOJ 3235】 3235: [Ahoi2013]好方的蛇 (单调栈+容斥原理)
3235: [Ahoi2013]好方的蛇
Time Limit: 10 Sec Memory Limit: 64 MB
Submit: 187 Solved: 95Description
有一天,可爱的蛇心花怒放,把自己变成了一个正方形!但是她改变的时候
被induce了导致改变出了些问题....按照预设,她应该变成一个N*N的全黑正方形,但是这个正方形出现了一些白的格子...现在她的身体不幸出了些小反应,定义一个subsnake是一个至少有两格的全黑矩形。
现在蛇想让你帮忙求一下一共有多少对不相交的subsnake,答案模10007。
Input
第一行一个整数 N, 接下来N行,每行一个长度为N的字符串,如果是B,那么是黑的,如果是 W那么是白的。
Output
一行一个整数,表示答案
Sample Input
3
BBW
BBW
BWWSample Output
5HINT
N<=1000
Source
【分析】
首先考虑白点不能选。f[i][j]表示以(i,j)为左上角的矩形个数。发现这个东西其实类似有障碍点的最大子矩阵问题。【其实求和更容易一些,用一个单调栈就好了。方法自己Y吧。。
但是怎么统计两两不相交呢?
首先枚举(i,j)为左上角的矩形,右下角在其左方或上方的矩形就是不相交的。
但是,有可能算重复。就是这种情况:

减掉就好了。
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define Maxn 1010
#define LL long long
#define Mod 10007 char s[Maxn][Maxn];
int mx[Maxn][Maxn],sm[Maxn][Maxn][];
int q[Maxn]; int n;
void ffind(int k)
{
if(k&)
{
for(int j=;j<=n;j++)
{
int l=,r=;q[]=;
for(int i=;i<=n;i++)
{
if(mx[i][j]==) {sm[i][j][k]=;q[r]=i;l=r+;continue;}
while(l<=r&&mx[i][j]<=mx[q[r]][j]) r--;
sm[i][j][k]=sm[q[r]][j][k]+(i-q[r])*mx[i][j];
q[++r]=i;
}
}
}
else
{
for(int j=;j<=n;j++)
{
int l=,r=;q[]=n+;
for(int i=n;i>=;i--)
{
if(mx[i][j]==) {sm[i][j][k]=;q[r]=i;l=r+;continue;}
while(l<=r&&mx[i][j]<=mx[q[r]][j]) r--;
sm[i][j][k]=sm[q[r]][j][k]+(q[r]-i)*mx[i][j];
q[++r]=i;
}
}
} for(int i=;i<=n;i++) for(int j=;j<=n;j++) if(sm[i][j][k]) sm[i][j][k]--;
if(k==) for(int i=n;i>=;i--) for(int j=;j<=n;j++)
sm[i][j][k]=(sm[i][j-][k]+sm[i+][j][k]-sm[i+][j-][k]+sm[i][j][k])%Mod;
else if(k==) for(int i=;i<=n;i++) for(int j=;j<=n;j++)
sm[i][j][k]=(sm[i][j-][k]+sm[i-][j][k]-sm[i-][j-][k]+sm[i][j][k])%Mod; } int main()
{
scanf("%d",&n);
for(int i=;i<=n;i++) scanf("%s",s[i]+); memset(mx,,sizeof(mx));
for(int i=;i<=n;i++) for(int j=n;j>=;j--) mx[i][j]=(s[i][j]=='W')?:mx[i][j]=+mx[i][j+];
ffind();//zuo shang
ffind();//zuo xia
for(int i=;i<=n;i++) for(int j=;j<=n;j++) mx[i][j]=(s[i][j]=='W')?:mx[i][j]=+mx[i][j-];
ffind();//you shang
ffind();//you xia int ans=;
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
{
ans+=1LL*sm[i][j][]*(sm[n][j-][]+sm[i-][n][]-sm[i-][j-][])%Mod;
ans-=1LL*sm[i][j][]*sm[i+][j-][]%Mod;
ans%=Mod;
}
ans=(ans+Mod)%Mod;
printf("%d\n",ans);
return ;
}
2017-04-20 10:52:07
【BZOJ 3235】 3235: [Ahoi2013]好方的蛇 (单调栈+容斥原理)的更多相关文章
- BZOJ 3235: [Ahoi2013]好方的蛇
BZOJ 3235: [Ahoi2013]好方的蛇 标签(空格分隔): OI-BZOJ OI-DP OI-容斥原理 Time Limit: 10 Sec Memory Limit: 64 MB Des ...
- 3235: [Ahoi2013]好方的蛇
3235: [Ahoi2013]好方的蛇 链接 分析: 可以求出以每个点为顶点的满足条件的矩形有多少个,单调栈求.设为sum. 然后对这个数组进行二维前缀和,可以求出每个矩阵内,以右下角.左下角为端点 ...
- BZOJ_3238_[Ahoi2013]差异_后缀数组+单调栈
BZOJ_3238_[Ahoi2013]差异_后缀数组+单调栈 Description Input 一行,一个字符串S Output 一行,一个整数,表示所求值 Sample Input cacao ...
- [BZOJ 3238] [AHOI 2013] 差异 【后缀数组 + 单调栈】
题目链接:BZOJ - 3238 题目分析 显然,这道题就是求任意两个后缀之间的LCP的和,这与后缀数组的联系十分明显. 求出后缀数组后,求出字典序相邻两个后缀的LCP,即 Height 数组. 那么 ...
- BZOJ3235 [Ahoi2013]好方的蛇 【单调栈 + dp】
题目链接 BZOJ3235 题解 求出每个点为顶点,分别求出左上,左下,右上,右下的矩形的个数\(g[i][j]\) 并预处理出\(f[i][j]\)表示点\((i,j)\)到四个角的矩形内合法矩形个 ...
- Bzoj 1657: [Usaco2006 Mar]Mooo 奶牛的歌声 单调栈
1657: [Usaco2006 Mar]Mooo 奶牛的歌声 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 631 Solved: 445[Submi ...
- BZOJ.4566.[HAOI2016]找相同字符(后缀数组 单调栈)
题目链接 给定两个字符串,求它们有多少个相同子串.相同串的位置不同算多个. POJ3145简化版. 后缀自动机做法见这儿,又快又好写(一下就看出差距了..) //13712kb 4076ms #inc ...
- BZOJ.1007.[HNOI2008]水平可见直线(凸壳 单调栈)
题目链接 可以看出我们是要维护一个下凸壳. 先对斜率从小到大排序.斜率最大.最小的直线是一定会保留的,因为这是凸壳最边上的两段. 维护一个单调栈,栈中为当前可见直线(按照斜率排序). 当加入一条直线l ...
- BZOJ3238 [Ahoi2013]差异 【后缀数组 + 单调栈】
题目链接 BZOJ3238 题解 简单题 经典后缀数组 + 单调栈套路,求所有后缀\(lcp\) #include<iostream> #include<cstdio> #in ...
随机推荐
- 【BZOJ】1576 [Usaco2009 Jan]安全路经Travel
[算法]最短路树+(树链剖分+线段树)||最短路树+并查集 [题解] 两种方法的思想是一样的,首先题目限制了最短路树唯一. 那么建出最短路树后,就是询问对于每个点断掉父边后重新找路径的最小值,其它路径 ...
- 2017ACM暑期多校联合训练 - Team 6 1003 HDU 6098 Inversion (模拟)
题目链接 Problem Description Give an array A, the index starts from 1. Now we want to know Bi=maxi∤jAj , ...
- 17 - 路径操作-shutil模块
目录 1 路径操作 1.1 os.path模块 1.2 pathlib模块 1.2.1 目录操作 1.2.2 文件操作 1.3 os 模块 2 shutil模块 2.1 copy复制 2.2 rm删除 ...
- python进阶之内置函数和语法糖触发魔法方法
前言 前面已经总结了关键字.运算符与魔法方法的对应关系,下面总结python内置函数对应的魔法方法. 魔法方法 数学计算 abs(args):返回绝对值,调用__abs__; round(args): ...
- linux常用命令一些解释
ls 命令是linux下最常用的命令.ls命令就是list的缩写缺省下ls用来打印出当前目录的清单如果ls指定其他目录那么就会显示指定目录里的文 件及文件夹清单. 通过ls 命令不仅可以查看li ...
- Codeforces Round #456 (Div. 2)
Codeforces Round #456 (Div. 2) A. Tricky Alchemy 题目描述:要制作三种球:黄.绿.蓝,一个黄球需要两个黄色水晶,一个绿球需要一个黄色水晶和一个蓝色水晶, ...
- puppet overview
安装 以在Ubuntu server 14.04.2 TLS 为例: 设置机器名. 编辑/etc/host以修改主机名,因为puppet是基于证书的,证书中包含主机名: 更新包源. echo -e & ...
- Python os模块和sys模块 操作系统的各种接口
一.os模块 这个模块提供了一个便携式去使用操作系统的相关功能,如果只是想操作路径,请参阅os.path模块. ''' os.getcwd() 获取当前工作目录,即当前python脚本工作的目录路径 ...
- oracle中的符号含义
1.Oracle数据库存储过程中:=是什么意思?答:赋值的意思.举例:str := 'abcd';将字符串abcd赋值给变量str. 2.oracle 存储过程中的 := 和=有什么区别?答::= 是 ...
- tomcat打开gzip、配置utf-8
在部署描述文件中配置如下内容:(web.xml) 打开gzip compression="on"配置utf-8 URIEncoding="UTF-8" < ...
.jpg)