NC216007. Go
描述
输入描述
There are multiple test cases. The first line of the input contains an integer indicating the number of test cases. For each test case:
The first line contains one integer () indicating the length of the board side.
For the next lines, the -th line contains a string ( , , ), where indicates that the intersection on the -th row and the -th column contains a black stone. Similarly for a white stone and for an empty intersection.
It's guaranteed that the sum of over all test cases does not exceed .
输出描述
For each test case output an integer modulo which is the answer encoded as follows:1. Sort all the stones with their row number (from top to bottom) as the primary sort key and their column number (from left to right) as the secondary sort key;2. , where is the number of stones and is the number of white stones not alive after flipping the color of the -th stone.NOTE that the MODULUS and the BASE are DIFFERENT.
示例1
输入:
3 2 .o .. 3 .x. xoo ox. 2 oo oo
输出:
0 870527216 485539347
C++(clang++11) 解法, 执行用时: 1852ms, 内存消耗: 229700K, 提交时间: 2021-02-04 16:17:19
#include <bits/stdc++.h> #define rep0(i,r) for (int i=0,i##end=r;i<i##end;++i) #define rep(i,l,r) for (int i=l;i<=r;++i) #define per(i,r,l) for (int i=r;i>=l;--i) #define ll long long using namespace std; const int V=2e6+6,B=1e6+7,P=1e9+7,dx[]={-1,0,1,0},dy[]={0,-1,0,1}; int n,a[V],c[V],sz[V],gas[V],rt[V],fa[V]; vector<int> G[V],T[V]; int dfn[V],dc,low[V],st[V],tp,nc; void Tarjan(int u){ dfn[u]=low[u]=++dc,st[++tp]=u; rep0(i,G[u].size()){ int v=G[u][i]; if (!dfn[v]){ Tarjan(v),low[u]=min(low[u],low[v]); if (low[v]==dfn[u]){ ++nc; for (int x=0;x!=v;--tp){ x=st[tp],T[nc].push_back(x),T[x].push_back(nc); } T[nc].push_back(u),T[u].push_back(nc); } } else low[u]=min(low[u],dfn[v]); } } void dfs(int u,int f){ sz[u]=u<=n*n&&a[u]==1,gas[u]=c[u],rt[u]=!f?u:rt[f],fa[u]=f; rep0(i,T[u].size()){ int v=T[u][i]; if (v!=f) dfs(v,u),sz[u]+=sz[v],gas[u]+=gas[v]; } } int ID(int x,int y){ return (x-1)*n+y; } bool in(int x,int y){ return 1<=x&&x<=n&&1<=y&&y<=n; } void adde(int u,int v){ G[u].push_back(v),G[v].push_back(u); } int main(){ int cas; scanf("%d",&cas); while (cas--){ scanf("%d",&n); rep(i,1,2*n*n) a[i]=c[i]=dfn[i]=rt[i]=0,T[i].clear(),G[i].clear(); rep(i,1,n){ static char s[2000]; scanf("%s",s); rep(j,1,n){ int u=ID(i,j); if (s[j-1]=='x') a[u]=2; else if (s[j-1]=='o') a[u]=1; else a[u]=-1; } } rep(i,1,n) rep(j,1,n){ int u=ID(i,j); if (i<n&&a[u]==1&&a[ID(i+1,j)]==1) adde(u,ID(i+1,j)); if (j<n&&a[u]==1&&a[ID(i,j+1)]==1) adde(u,ID(i,j+1)); rep(w,0,3) if (in(i+dx[w],j+dy[w])) c[u]+=a[ID(i+dx[w],j+dy[w])]==-1; } int cnt=0; nc=n*n,dc=tp=0; rep(i,1,n) rep(j,1,n){ int u=ID(i,j); if (!dfn[u]) Tarjan(u),dfs(u,0),cnt+=!gas[u]?sz[u]:0; } int ans=0; rep(i,1,n) rep(j,1,n) if (a[ID(i,j)]==1){ int u=ID(i,j),d=!gas[rt[u]]?-sz[rt[u]]:0; rep0(k,T[u].size()){ int v=T[u][k]; if (v!=fa[u]) d+=!gas[v]?sz[v]:0; else d+=gas[rt[u]]-gas[u]==0?sz[rt[u]]-sz[u]:0; } ans=((ll)ans*B+cnt+d)%P; } else if (a[ID(i,j)]==2){ int d=0,g=c[ID(i,j)],s=1; rep(w,0,3){ int x=i+dx[w],y=j+dy[w]; if (in(x,y)&&a[ID(x,y)]==1){ int u=rt[ID(x,y)]; bool t=false; rep(w0,0,w-1) if (in(i+dx[w0],j+dy[w0])&&rt[ID(i+dx[w0],j+dy[w0])]==u){ t=true; break; } if (t) continue; if (!gas[u]) d-=sz[u]; g+=gas[u],s+=sz[u]; } } if (!g) d+=s; ans=((ll)ans*B+cnt+d)%P; } printf("%d\n",ans); } return 0; }