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]好方的蛇的更多相关文章

  1. 【BZOJ 3235】 3235: [Ahoi2013]好方的蛇 (单调栈+容斥原理)

    3235: [Ahoi2013]好方的蛇 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 187  Solved: 95 Description 有一天, ...

  2. 3235: [Ahoi2013]好方的蛇

    3235: [Ahoi2013]好方的蛇 链接 分析: 可以求出以每个点为顶点的满足条件的矩形有多少个,单调栈求.设为sum. 然后对这个数组进行二维前缀和,可以求出每个矩阵内,以右下角.左下角为端点 ...

  3. BZOJ3235 [Ahoi2013]好方的蛇 【单调栈 + dp】

    题目链接 BZOJ3235 题解 求出每个点为顶点,分别求出左上,左下,右上,右下的矩形的个数\(g[i][j]\) 并预处理出\(f[i][j]\)表示点\((i,j)\)到四个角的矩形内合法矩形个 ...

  4. BZOJ 3233: [Ahoi2013]找硬币

    BZOJ 3233: [Ahoi2013]找硬币 标签(空格分隔): OI-BZOJ OI-DP Time Limit: 10 Sec Memory Limit: 64 MB Description ...

  5. BZOJ 3233: [Ahoi2013]找硬币( dp )

    dp(x)表示最大面值为x时需要的最少硬币数. 枚举x的质因数p,  dp(x) = min( dp(x/p) - (p-1) * sigma[a[i]/x] ). ----------------- ...

  6. BZOJ 3238: [Ahoi2013]差异 [后缀数组 单调栈]

    3238: [Ahoi2013]差异 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 2326  Solved: 1054[Submit][Status ...

  7. BZOJ 3237: [Ahoi2013]连通图

    3237: [Ahoi2013]连通图 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 1161  Solved: 399[Submit][Status ...

  8. BZOJ 3236: [Ahoi2013]作业

    3236: [Ahoi2013]作业 Time Limit: 100 Sec  Memory Limit: 512 MBSubmit: 1393  Solved: 562[Submit][Status ...

  9. Bzoj 3236: [Ahoi2013]作业 莫队,分块

    3236: [Ahoi2013]作业 Time Limit: 100 Sec  Memory Limit: 512 MBSubmit: 1113  Solved: 428[Submit][Status ...

随机推荐

  1. 6 GPath

    1       GPath GPath是Groovy的表达式语言,类似xml的XPath.而二者的不同在于,GPath表达式可以应用于处理POJOs或者处理xml. 例如:a.b.c语句等同于a.ge ...

  2. python模块之urllib

    python文档官网地址:https://docs.python.org/3.6/library/urllib.html?highlight=urllib urllib 是一个收集以下模块以处理URL ...

  3. shell中的命令与特殊符号

    1.记录命令:! !!:连续的“!”表示执行上一次的指令 !n:表示执行命令历史中第二条指令 注:!2居然给我关机了 !字符串(字符串大于1)表示执行命令历史中最近的一次 2.通配符 " * ...

  4. 如何在eclipse使用git插件

    how to commit file to remote? --> Team --> Synchronize Workspace --> add to index --> co ...

  5. 前台js escape及后台C# Server.UrlEncode 对QueryString传参的含~!@#$%^&*等特殊字符的处理

    通常情况下,我们在List列表页面,会包含Create,Edit,Delete等操作按钮, 而通常的处理是: Create按钮跳转到DataCreate.aspx Edit按钮跳转到DataEdit. ...

  6. (转)Awk使用案例总结(运维必会)

    以下知识点可能有不对之处,请参考最新Awk学习文章:http://lizhenliang.blog.51cto.com/7876557/1892112 原文:http://blog.51cto.com ...

  7. SVN仓库连同版本信息迁移新服务器的步骤

    SVN仓库连同版本信息迁移新服务器的步骤 步骤一:导出(1)链接原服务器,找到SVN Server安装路径下的bin文件,并复制文件路径,如 C:\Program File\SVN Server\bi ...

  8. vue中添加echarts

    方法一:全局引入echarts 步骤: 1.全局安装 echarts依赖.        cnpm install echarts -- save 2.引入echarts模块,在Vue项目的main. ...

  9. asp.net 单元测试(转)

    最早接触单元测试是看了极限编程相关资料里边讲的测试驱动开发,然后下载了Nunit研究了一下,但并没产生多大的触动,因为那个时候做的都是些时间紧任务重的事情,对于单元测试的直接感觉就是有可能比较费时间. ...

  10. postMessage解决跨域跨窗口消息传递

    平时做web开发的时候关于消息传递,除了客户端与服务器传值还有几个经常会遇到的问题 页面和其打开的新窗口的数据传递 页面与嵌套的iframe消息传递 这些问题都有一些解决办法,但html5引入的mes ...