zoukankan      html  css  js  c++  java
  • 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;
    }
    
    
  • 相关阅读:
    Spring依赖注入servlet会话监听器
    Maven常用命令
    页面获取Spring Security登录用户
    spring security:ajax请求的session超时处理
    前端用Request Payload方式请求后台
    记一次网易前端实习面试【转载】
    JavaScript函数内部修改全局变量的问题【一道面试题】
    Js作用域与作用域链详解
    js测试
    JavaScript 中对变量和函数声明的“提前(hoist)”
  • 原文地址:https://www.cnblogs.com/wuyuhan/p/5270042.html
Copyright © 2011-2022 走看看