树状数组一般都是计数问题,这个题目也不例外,我们可以发现题目讲的很复杂,但是换一种理解方式(或者画图可以知道),行列是可以单独考虑的,单独考虑行列,一行和一列一定是存在交点的,对于两个相同的行/列出现了,就等同于这里没有行/列了,我们只需要维护拿树状数组区间有多少行列就行了.
代码如下:
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int N=1e5+5; int sum[2][N];//维护矩阵中行列有多少. int dx[N],dy[N]; int lowbit(int x) { return x&(-x); } int n,m; void add(int pos,int val,int op) { while(pos<=N-5) { sum[op][pos]+=val; pos+=lowbit(pos); } } ll query(int pos,int op) { ll res=0; while(pos) { res+=sum[op][pos]; pos-=lowbit(pos); } return res; } int main() { int q; scanf("%d%d%d",&n,&m,&q);//矩阵大小和q组询问1. while(q--) { ll x1,y1,x2,y2; int x,y,c; scanf("%d",&c); if(c==1) { scanf("%d%d",&x,&y); if(dx[x]&1) { add(x,-1,0); }//减. else { add(x,1,0); }//加 if(dy[y]&1) { add(y,-1,1); }//减. else { add(y,1,1); }//加 dx[x]++,dy[y]++; } else { scanf("%lld%lld%lld%lld",&x1,&y1,&x2,&y2); printf("%lld\n",(query(y2,1)-query(y1-1,1))*(x2-x1+1)+(y2-y1+1)*(query(x2,0)-query(x1-1,0))-2ll*(query(x2,0)-query(x1-1,0))*(query(y2,1)-query(y1-1,1))); } } return 0; }
自认为自己代码最好看hh...(菜鸡调侃