NC19893. [AHOI2013]好方的蛇
描述
输入描述
第一行一个整数 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; }