您的位置:首页 > 其它

AGC 015C Nuske vs Phantom Thnook 思维+二维前缀和

2017-05-27 23:07 337 查看
点击打开链接

题意:n*m矩阵,n,m<=2e3,矩阵中的1能走到相邻4个1上,0代表障碍,若两个1联通 则只有一条路径 

q个询问,q<=2e5,每次询问一个子矩阵中有多少个连通分量?

同一个连通分量中任意两点只有一条路径,于是对相邻的每个1连接一条边,每一个连通分量显然都为一颗树

若子矩形有k个联通分量,因为每个联通分量都为树,则子矩形中点数-边数等于k 利用二维前缀和求出子矩形1的个数(点)和相邻1(边)个数即可 复杂度O(mn+q)

#include <bits/stdc++.h>
using namespace std;
const int N=2e3+20;
typedef long long ll;
int n,m,q;
int f

,h

,g

;//f[i][j] (0,0)~(i,j)中有多少个1
//h,g 水平和竖直相邻的边
char s

;
int main()
{
while(cin>>n>>m>>q)
{
for(int i=1;i<=n;i++)
scanf("%s",s[i]+1);
memset(f,0,sizeof(f));
memset(h,0,sizeof(h));
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
f[i][j]=f[i-1][j]+f[i][j-1]-f[i-1][j-1]+(s[i][j]-'0');
int cnt=0,res=0;
if(s[i][j]=='1')
{
if(s[i-1][j]=='1')
res++;
if(s[i][j-1]=='1')
cnt++;
}
h[i][j]=h[i-1][j]+h[i][j-1]-h[i-1][j-1]+cnt;
g[i][j]=g[i-1][j]+g[i][j-1]-g[i-1][j-1]+res;
// cout<<g[i][j]<<' ';
}
}
int x1,y1,x2,y2;
while(q--)
{
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
int ans=f[x2][y2]-f[x2][y1-1]-f[x1-1][y2]+f[x1-1][y1-1];
int cnt=h[x2][y2]-h[x2][y1]-h[x1-1][y2]+h[x1-1][y1];
int res=g[x2][y2]-g[x1][y2]-g[x2][y1-1]+g[x1][y1-1];
ans-=cnt+res;
printf("%d\n",ans);
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: