[BZOJ3235][Ahoi2013]好方的蛇(单调栈+容斥原理)
来源:互联网 发布:深圳市市政院 知乎 编辑:程序博客网 时间:2024/06/06 01:20
题目描述
传送门
题解
heheda管这叫小学生容斥
首先求出以某一个点为左上角、左下角、右上角、右下角的矩形的数量
这个没法dp,但是可以直接用一个单调栈求出来。预处理出某一个点向上向下最远延伸到的长度,单调栈中的每一个点都是能组成矩形的合法顶点
然后枚举每一个点(i,j),以这个点为左上角的矩形可以和除去i..n,j..n范围内的矩形配对,这样利用右下角矩形数量的二维前缀和加加减减能得到答案
但是这样做发现一个问题,有一些右上-左下的行列都不相交的矩形被重复统计了,所以还要减去这一部分。同样枚举一个点(i,j),以这个点为左下角的矩形可以和1..i,j..n范围内的矩形配对,也就是左下角矩形数的二维前缀和和
代码
#include<algorithm>#include<iostream>#include<cstring>#include<cstdio>#include<cmath>using namespace std;#define N 1005#define Mod 10007int n,ans;char s[N][N];int stack[N],cnt[N],up[N][N],down[N][N],rd[N][N],ru[N][N],ld[N][N],lu[N][N];int main(){ scanf("%d",&n); for (int i=1;i<=n;++i) scanf("%s",s[i]+1); for (int i=1;i<=n;++i) for (int j=1;j<=n;++j) if (s[i][j]=='W') continue; else up[i][j]=up[i-1][j]+1; for (int i=n;i>=1;--i) for (int j=n;j>=1;--j) if (s[i][j]=='W') continue; else down[i][j]=down[i+1][j]+1; for (int i=1;i<=n;++i) { int top=0,tot=0; for (int j=1;j<=n;++j) { int now=1; while (top&&up[i][j]<=stack[top]) { tot-=stack[top]*cnt[top]; now+=cnt[top]; --top; } stack[++top]=up[i][j],cnt[top]=now,tot+=now*up[i][j]; if (tot) rd[i][j]=tot-1; } } for (int i=n;i>=1;--i) { int top=0,tot=0; for (int j=n;j>=1;--j) { int now=1; while (top&&down[i][j]<=stack[top]) { tot-=stack[top]*cnt[top]; now+=cnt[top]; --top; } stack[++top]=down[i][j],cnt[top]=now,tot+=now*down[i][j]; if (tot) lu[i][j]=tot-1; } } for (int i=1;i<=n;++i) { int top=0,tot=0; for (int j=n;j>=1;--j) { int now=1; while (top&&up[i][j]<=stack[top]) { tot-=stack[top]*cnt[top]; now+=cnt[top]; --top; } stack[++top]=up[i][j],cnt[top]=now,tot+=now*up[i][j]; if (tot) ld[i][j]=tot-1; } } for (int i=n;i>=1;--i) { int top=0,tot=0; for (int j=1;j<=n;++j) { int now=1; while (top&&down[i][j]<=stack[top]) { tot-=stack[top]*cnt[top]; now+=cnt[top]; --top; } stack[++top]=down[i][j],cnt[top]=now,tot+=now*down[i][j]; if (tot) ru[i][j]=tot-1; } } for (int i=1;i<=n;++i) for (int j=1;j<=n;++j) { rd[i][j]+=rd[i-1][j]+rd[i][j-1]-rd[i-1][j-1]; rd[i][j]%=Mod; } for (int i=n;i>=1;--i) for (int j=1;j<=n;++j) { ru[i][j]+=ru[i][j-1]+ru[i+1][j]-ru[i+1][j-1]; ru[i][j]%=Mod; ld[i][j]%=Mod;lu[i][j]%=Mod; } for (int i=1;i<=n;++i) for (int j=1;j<=n;++j) { ans+=lu[i][j]*(rd[i-1][n]+rd[n][j-1]-rd[i-1][j-1]); ans-=ld[i][j]*ru[i+1][j-1]; ans=(ans%Mod+Mod)%Mod; } printf("%d\n",ans);}
0 0
- [BZOJ3235][Ahoi2013]好方的蛇(单调栈+容斥原理)
- bzoj 3235: [Ahoi2013]好方的蛇
- hdu4059 容斥原理的好题
- bzoj 3238: [Ahoi2013]差异(后缀数组+单调栈)
- HDU 6052 To my boyfriend(分块+容斥原理+单调栈)
- 【bzoj3238】[Ahoi2013]差异 后缀数组+单调栈
- 【bzoj3238】[Ahoi2013]差异 后缀数组+单调栈
- 【bzoj3238】【AHOI2013】【差异】【后缀数组+单调栈】
- 后缀数组+单调栈 【Ahoi2013】bzoj3238 差异
- bzoj 3238 Ahoi2013 后缀数组+单调栈
- [BZOJ4558][JLoi2016]方(数学相关+容斥原理)
- hdoj Coprime 5072 (容斥原理) 好题***
- HDU 2841 Visible Trees (容斥原理好题)
- 【HDU 2841】Visible Trees(容斥原理-好题)
- [BZOJ3622]已经没有什么好害怕的了(dp+容斥原理+组合数学)
- bzoj 3622: 已经没有什么好害怕的了 (容斥原理+DP)
- [BZOJ3622]已经没有什么好害怕的了(容斥原理+DP)
- [BZOJ3238][Ahoi2013]差异(后缀数组+单调栈||后缀自动机+树形dp)
- The content of element type "session-factory" must match "(property*,mapping*,(class-cache|collectio
- bzoj1088: [SCOI2005]扫雷Mine
- 允许远程访问MySQL
- Python轻松入门-33 字典计算
- SSM框架——实现分页和搜索分页
- [BZOJ3235][Ahoi2013]好方的蛇(单调栈+容斥原理)
- SSM框架——以注解形式实现事务管理
- Qt/QML 窗口阴影边框实现
- 【CodeForces】484E Sign on Fence
- Oil Deposits HDU
- 再写dll 关于declspec(dllexport)和declspec(dllimport)
- c语言中的main函数讨论
- local response normalization/batch normalization
- 输入一个数对应二进制下遇到的问题归纳