BZOJ 3235: [Ahoi2013]好方的蛇
BZOJ 3235: [Ahoi2013]好方的蛇
标签(空格分隔): OI-BZOJ OI-DP OI-容斥原理
Time Limit: 10 Sec
Memory Limit: 64 MB
Description
有一天,可爱的蛇心花怒放,把自己变成了一个正方形!但是她改变的时候
被induce了导致改变出了些问题....
按照预设,她应该变成一个N*N的全黑正方形,但是这个正方形出现了一些白的格子...现在她的身体不幸出了些小反应,定义一个subsnake是一个至少有两格的全黑矩形。
现在蛇想让你帮忙求一下一共有多少对不相交的subsnake,答案模10007。
Input
第一行一个整数 N, 接下来N行,每行一个长度为N的字符串,如果是B,那么是黑的,如果是 W那么是白的。
Output
一行一个整数,表示答案
Sample Input
3
BBW
BBW
BWW
Sample Output
5
HINT
N<=1000
Solution####
dp计数题
首先可以用单调栈维护以某个点为右下角可能的矩形个数设为sum[i][j]
求出f[i][j]表示在[1-i][1-j]内的矩形个数,转移为
f[i][j]=f[i-1][j]+f[i][j-1]-f[i-1][j-1]+sum[i][j];
这样可以用f[i][n]表示下边界在i以内的矩形个数。
也可求出上边界为i的矩形个数
然后可以算出,可以被一条横线分开的矩形个数
同理可以算出,可以被一条竖线分开的矩形个数
发现这样2种情况会被统计多次:
1100
1100
0011
0011
或
0011
0011
1100
1100
对于第一种情况可以枚举右下正方形的左上端点然后用f统计
第二种类似。
Code####
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<queue>
#include<set>
#include<map>
#include<bitset>
#include<vector>
using namespace std;
#define PA pair<int,int>
int read()
{
int s=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){s=(s<<1)+(s<<3)+ch-'0';ch=getchar();}
return s*f;
}
int n,mo=10007,ans;
bool p[1005][1005];
int f[1005][1005],g[1005][1005],u[1005],sum;
int s1[1005],s2[1005],s3[1005],tot;
char z[1005];
int main()
{
//freopen(".in","r",stdin);
//freopen(".out","w",stdout);
n=read();
for(int i=1;i<=n;i++)
{scanf("%s",z);
for(int j=1;j<=n;j++)
p[i][j]=(z[j-1]=='B');
}
for(int i=1;i<=n;i++)u[i]=0;
for(int i=1;i<=n;i++)
{for(int j=1;j<=n;j++)
u[j]=(p[i][j]?u[j]+1:0);
tot=sum=0;
for(int j=1;j<=n;j++)
{int k=0;
while(tot&&s1[tot]>u[j])k+=s2[tot],sum-=s3[tot--];
tot++;k++;
s1[tot]=u[j];s2[tot]=k;s3[tot]=u[j]*k;
sum+=s3[tot]-p[i][j];
f[i][j]=f[i-1][j]+f[i][j-1]-f[i-1][j-1]+sum;f[i][j]%=mo;
sum+=p[i][j];
}
}
for(int i=1;i<=n;i++)u[i]=0;
for(int i=1;i<=n;i++)
{for(int j=1;j<=n;j++)
u[j]=(p[i][j]?u[j]+1:0);
tot=sum=0;
for(int j=n;j>=1;j--)
{int k=0;
while(tot&&s1[tot]>u[j])k+=s2[tot],sum-=s3[tot--];
tot++;k++;
s1[tot]=u[j];s2[tot]=k;s3[tot]=u[j]*k;
sum+=s3[tot]-p[i][j];
g[i][j]=g[i-1][j]+g[i][j+1]-g[i-1][j+1]+sum;g[i][j]%=mo;
sum+=p[i][j];
}
}
for(int i=1;i<=n;i++)u[i]=0;
for(int i=n;i>=1;i--)
{for(int j=1;j<=n;j++)
u[j]=(p[i][j]?u[j]+1:0);
tot=sum=0;
for(int j=n;j>=1;j--)
{int k=0;
while(tot&&s1[tot]>u[j])k+=s2[tot],sum-=s3[tot--];
tot++;k++;
s1[tot]=u[j];s2[tot]=k;s3[tot]=u[j]*k;
sum+=s3[tot]-p[i][j];
ans+=sum*f[n][j-1]+sum*f[i-1][n]-sum*f[i-1][j-1];ans%=mo;
sum+=p[i][j];
}
}
for(int i=1;i<=n;i++)u[i]=0;
for(int i=n;i>=1;i--)
{for(int j=1;j<=n;j++)
u[j]=(p[i][j]?u[j]+1:0);
tot=sum=0;
for(int j=1;j<=n;j++)
{int k=0;
while(tot&&s1[tot]>u[j])k+=s2[tot],sum-=s3[tot--];
tot++;k++;
s1[tot]=u[j];s2[tot]=k;s3[tot]=u[j]*k;
sum+=s3[tot]-p[i][j];
ans-=sum*g[i-1][j+1];ans%=mo;
sum+=p[i][j];
}
}
cout<<(ans+mo)%mo<<endl;
//fclose(stdin);
//fclose(stdout);
return 0;
}
BZOJ 3235: [Ahoi2013]好方的蛇的更多相关文章
- 【BZOJ 3235】 3235: [Ahoi2013]好方的蛇 (单调栈+容斥原理)
3235: [Ahoi2013]好方的蛇 Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 187 Solved: 95 Description 有一天, ...
- 3235: [Ahoi2013]好方的蛇
3235: [Ahoi2013]好方的蛇 链接 分析: 可以求出以每个点为顶点的满足条件的矩形有多少个,单调栈求.设为sum. 然后对这个数组进行二维前缀和,可以求出每个矩阵内,以右下角.左下角为端点 ...
- BZOJ3235 [Ahoi2013]好方的蛇 【单调栈 + dp】
题目链接 BZOJ3235 题解 求出每个点为顶点,分别求出左上,左下,右上,右下的矩形的个数\(g[i][j]\) 并预处理出\(f[i][j]\)表示点\((i,j)\)到四个角的矩形内合法矩形个 ...
- BZOJ 3233: [Ahoi2013]找硬币
BZOJ 3233: [Ahoi2013]找硬币 标签(空格分隔): OI-BZOJ OI-DP Time Limit: 10 Sec Memory Limit: 64 MB Description ...
- BZOJ 3233: [Ahoi2013]找硬币( dp )
dp(x)表示最大面值为x时需要的最少硬币数. 枚举x的质因数p, dp(x) = min( dp(x/p) - (p-1) * sigma[a[i]/x] ). ----------------- ...
- BZOJ 3238: [Ahoi2013]差异 [后缀数组 单调栈]
3238: [Ahoi2013]差异 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 2326 Solved: 1054[Submit][Status ...
- BZOJ 3237: [Ahoi2013]连通图
3237: [Ahoi2013]连通图 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 1161 Solved: 399[Submit][Status ...
- BZOJ 3236: [Ahoi2013]作业
3236: [Ahoi2013]作业 Time Limit: 100 Sec Memory Limit: 512 MBSubmit: 1393 Solved: 562[Submit][Status ...
- Bzoj 3236: [Ahoi2013]作业 莫队,分块
3236: [Ahoi2013]作业 Time Limit: 100 Sec Memory Limit: 512 MBSubmit: 1113 Solved: 428[Submit][Status ...
随机推荐
- CENTOS7下安装REDIS4.0.11
拷贝收藏私用,别无他意,原博客地址: https://www.cnblogs.com/zuidongfeng/p/8032505.html 1.安装redis 第一步:下载redis安装包 wget ...
- JAVA中 List和ArrayList的区别
List是一个接口,而ListArray是一个类. ListArray继承并实现了List. 所以List不能被构造,但可以向上面那样为List创建一个引用,而ListArray就可以被构造. ...
- 效率工具(fswatch,rsync)
mac 安装 brew: ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/in ...
- CAD安装失败怎样卸载CAD 2016?错误提示某些产品无法安装
AUTODESK系列软件着实令人头疼,安装失败之后不能完全卸载!!!(比如maya,cad,3dsmax等).有时手动删除注册表重装之后还是会出现各种问题,每个版本的C++Runtime和.NET f ...
- Kudu Tablet design
不多说,直接上干货! http://blog.csdn.net/lookqlp/article/details/51416829
- 《Flink 源码解析》—— 源码编译运行
更新一篇知识星球里面的源码分析文章,去年写的,周末自己录了个视频,大家看下效果好吗?如果好的话,后面补录发在知识星球里面的其他源码解析文章. 前言 之前自己本地 clone 了 Flink 的源码,编 ...
- java学习第十二天
1:Scanner的使用(了解) (1)在JDK5以后出现的用于键盘录入数据的类. (2)构造方法: A:讲解了System.in这个东西. 它其实是标准的输入流,对应于键盘录入 B:构造方法 Inp ...
- C# 使用消息队列,包括远程访问
转:https://www.cnblogs.com/80X86/p/5557801.html 功能需求,用到了队列,用的时候出了很多问题,现在总结一下,希望能对有需要的人提供帮助. 我的需求很简单,就 ...
- 自定义input文件上传 file的提示文字及样式
简单记录一下 效果图: 代码: <input class="aload" type='button' value='上传附件' onClick='javascript:$(& ...
- npm EPERM: operation not permitted, rename解决
此问题并非权限问题! 执行如下3条命令解决: 1.清理npm缓存 npm cache clean --force 2.升级npm版本 npm install -g npm@latest --force ...