列表

详情


NC19893. [AHOI2013]好方的蛇

描述

有一天,可爱的蛇心花怒放,把自己变成了一个正方形!但是她改变的时候 被induce了导致改变出了些问题....    
按照预设,她应该变成一个N*N的全黑正方形,但是这个正方形出现了一些白的格子...
现在她的身体不幸出了些小反应,定义一个subsnake是一个至少有两格的全黑矩形。
   
现在蛇想让你帮忙求一下一共有多少对不相交的subsnake,答案模10007。

输入描述

第一行一个整数 N,接下来N行,每行一个长度为N的字符串,如果是B,那么是黑的,如果是 W那么是白的。

输出描述

一行一个整数,表示答案

示例1

输入:

3 
BBW
BBW 
BWW

输出:

5

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++11(clang++ 3.9) 解法, 执行用时: 75ms, 内存消耗: 9208K, 提交时间: 2019-03-16 14:08:17

#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;
}

上一题