[agc015c]nuske vs phantom thnook

题意:

有一个n*m的网格图,每个格子是蓝色或白色。四相邻的两个格子连一条边,保证蓝格子构成一个森林。

有q组询问,每次询问给出一个矩形,问矩形内蓝格子组成的联通块个数。

$1\leq n,m\leq 2000$

$1\leq q\leq200000$

题解:

结论:联通块数=点数-边数

二维前缀和乱搞,没了。

代码:

 1 #include<algorithm>
 2 #include<iostream>
 3 #include<cstring>
 4 #include<cstdio>
 5 #include<cmath>
 6 #include<queue>
 7 #define inf 2147483647
 8 #define eps 1e-9
 9 using namespace std;
10 typedef long long ll;
11 int n,m,q,x,y,_x,_y,a[2001][2001],pre[2001][2001],h[2001][2001],l[2001][2001],s[2001][2001];
12 char st[2001];
13 int main(){
14     memset(a,0,sizeof(a));
15     scanf("%d%d%d",&n,&m,&q);
16     for(int i=1;i<=n;i++){
17         scanf("%s",st+1);
18         for(int j=1;j<=m;j++){
19             a[i][j]=(st[j]=='1');
20             pre[i][j]=a[i][j]+pre[i-1][j]+pre[i][j-1]-pre[i-1][j-1];
21             l[i][j]=(a[i][j]==a[i-1][j]&&a[i][j])+l[i-1][j]+l[i][j-1]-l[i-1][j-1];
22             h[i][j]=(a[i][j]==a[i][j-1]&&a[i][j])+h[i-1][j]+h[i][j-1]-h[i-1][j-1];
23         }
24     }
25     while(q--){
26         scanf("%d%d%d%d",&x,&y,&_x,&_y);
27         printf("%d\n",pre[_x][_y]-pre[x-1][_y]-pre[_x][y-1]+pre[x-1][y-1]-\
28                       (l[_x][_y]-l[x][_y]-l[_x][y-1]+l[x][y-1])-\
29                       (h[_x][_y]-h[x-1][_y]-h[_x][y]+h[x-1][y]));
30     }
31     return 0;
32 }

 

posted @ 2018-09-14 19:57  DCDCBigBig  阅读(204)  评论(0编辑  收藏  举报