题目链接
https://ac.nowcoder.com/acm/problem/15172
题目大意
矩阵由0,1构成,n行n列;m次询问,操作数为1时,对某个坐标处的数值翻转,即0变1,1变0;操作数为2时,求一个坐标为子矩阵左上角坐标,另一个坐标为子矩阵右上角坐标的子矩阵和并输出。
解题思路
我的思路:
二维数组a,表示每个灯泡的状态;二维数组c,为树状数组。
a[i][j]表示第i行第j个灯泡的状态,c[i][j]表示第i行所处的树状数组,举例:c[1]表示第一行树状数组首地址,也就是每行有独立的树状数组存储。
AC代码
#include<bits/stdc++.h> using namespace std; const int N=1e3+5; bool a[N][N]; int c[N][N]; int n,m; int lowbit(int x){ return x&(-x); } void update(int x,int y){ int f; if(a[x][y]) f=-1;//进入前为亮,翻转后,变为灭,所以c数组要进行-1操作 else f=1; a[x][y]^=1;//取反;在输入阶段,也是对a数组的赋值 while(y<=n){ c[x][y]+=f; y+=lowbit(y); } } int getsum(int x,int y){ int sum=0; while(y>0){ sum+=c[x][y]; y-=lowbit(y); } return sum; } int main(){ cin>>n>>m; //init for(int i=1;i<=n;i++) for(int j=1;j<=n;j++){ bool tmp; cin>>tmp; if(tmp) update(i,j); } for(int i=1;i<=m;i++){ int op; cin>>op; if(op==1){ int x,y; cin>>x>>y; update(x,y); } else{ int sum=0; int x1,y1,x2,y2; cin>>x1>>y1>>x2>>y2; if(x1>x2) swap(x1,x2);//对于本题的数据而言可有可无 if(y1>y2) swap(y1,y2);//同上 for(int i=x1;i<=x2;i++)//每行累加 sum+=getsum(i,y2)-getsum(i,y1-1); cout<<sum<<endl; } } }
大佬思路
一维数组,a,c还是一样的意义,通过二维数组转变为一维数组,其实本质还是不变的。
输出结果,还是要每行累加。
注意列序号不能从0开始了,行序号可以从0开始,因为在通过前缀和求一段区间的和的时候,假如区间左端点包含0,那么答案应该为(右端点位置)的值-(左端点-1位置)的值,但是不存在数组索引不存在-1,稍微注意一下。
AC代码
#include<bits/stdc++.h> using namespace std; const int N=1e6+50; int a[N]; int c[N]; int n,m; int lowbit(int x){ return x&-x; } void update(int x,int add){ while(x<=n*n){ c[x]+=add; x+=lowbit(x); } } int getsum(int x){ int sum=0; while(x>0){ sum+=c[x]; x-=lowbit(x); } return sum; } int endans(int s,int b){ return getsum(b)-getsum(s-1); } int main(){ cin>>n>>m; for(int i=0;i<n;i++) for(int j=1;j<=n;j++){ cin>>a[i*n+j]; if(a[i*n+j]==1) update(i*n+j,1); } for(int i=1;i<=m;i++){ int op; cin>>op; if(op==1){ int x,y; cin>>x>>y; if(a[(x-1)*n+y]==1) {a[(x-1)*n+y]=0;update((x-1)*n+y,-1);} else {a[(x-1)*n+y]=1;update((x-1)*n+y,1);} } else{ int ans=0; int x1,x2,y1,y2; cin>>x1>>y1>>x2>>y2; if(x1>x2) swap(x1,x2); if(y1>y2) swap(y1,y2); for(int i=x1-1;i<x2;i++) ans+=endans(i*n+y1,i*n+y2); cout<<ans<<endl; } } }