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;
}
题意: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;
}
相关文章推荐
- BZOJ2241:打地鼠(二维前缀和 & 思维)
- Codeforces 835C Star sky【思维+暴力预处理二维前缀和】
- AtCoder Regular Contest 089 D - Checker 思维题、点的转移、二维前缀和
- Codeforces 106D Treasure Island【思维+二维前缀和】
- AtCoder:Nuske vs Phantom Thnook(思维 & 树)
- Atcoder 500 Checker 思维+二维前缀和
- Codeforces835C-Star sky(二维前缀和+思维)
- BZOJ 1218: [HNOI2003]激光炸弹 二维前缀和,暴力
- Hrbust 1742 Enclosure Plan【二维前缀和+尺取法】
- AtCoder Grand Contest 015 C.Nuske vs Phantom Thnook
- CDOJ 1256 二维前缀和处理
- 51nod 1393 0和1相等串 (思维+前缀和)
- codeforces 816-B. Karen and Coffee(前缀和+思维)
- codeforces835 b贪心 c 二维前缀和
- Color the ball 前缀和+思维
- 洛谷Oj-创意吃鱼法-二维前缀和/二维动态规划
- 【前缀和 && 思维转换】ICM Technex 2017 and Codeforces Round #400 (Div. 1 + Div. 2, combined)Molly's Chemicals
- 611C. New Year and Domino【二维前缀和】【容斥】
- FJUT 3087 【前缀好题 + 思维】
- [AtCoder][杂题]AGC015 . C .Nuske vs Phantom Thnook