题目描述
经过上次失败后,蕾米莉亚决定再次发动红雾异变,但为了防止被灵梦退治,她决定将红雾以奇怪的阵势释放。
我们将幻想乡看做是一个 n×mn \times mn×m的方格地区,一开始没有任何一个地区被红雾遮盖。蕾米莉亚每次站在某一个地区上,向东南西北四个方向各发出一条无限长的红雾,可以影响到整行/整列,但不会影响到她所站的那个地区。如果两阵红雾碰撞,则会因为密度过大而沉降消失。灵梦察觉到了这次异变,决定去解决它。但在解决之前,灵梦想要了解一片范围红雾的密度。可以简述为两种操作:
1 x y 蕾米莉亚站在坐标 \((x,y)\) 的位置向四个方向释放无限长的红雾。
2 x1 y1 x2 y2 询问左上点为\((x1,y1)\),右下点为 \((x2,y2)\) 的矩形范围内,被红雾遮盖的地区的数量。
输入格式
第一行三个整数 \(n,m,q\),表示幻想乡大小为 \(n \times m\),有 \(q\) 个询问。
接下来 \(q\) 行,每行 \(3\) 个或 \(5\) 个整数,用空格隔开,含义见题目描述。
输出格式
对于每一个操作 \(2\),输出一行一个整数,表示对应询问的答案。
#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=1e5+5;
#define int long long
int n,m,q,c[N][2];
inline void add(int x,int y,int op){
for(;x<N;x+=x&(-x))c[x][op]+=y;
}
inline int sum(int x,int op){
int ans=0;
for(;x;x-=x&(-x))ans+=c[x][op];
return ans;
}
signed main(){
cin>>n>>m>>q;
int t,x,y,x1,x2,y1,y2;
while(q--){
scanf("%lld",&t);
if(t==1){
scanf("%lld%lld",&x,&y);
if(sum(x,0)-sum(x-1,0))add(x,-1,0);
else add(x,1,0);
if(sum(y,1)-sum(y-1,1))add(y,-1,1);
else add(y,1,1);
}else{
scanf("%lld%lld%lld%lld",&x1,&y1,&x2,&y2);
x=sum(x2,0)-sum(x1-1,0),y=sum(y2,1)-sum(y1-1,1);
int ans=(y2-y1+1)*x+(x2-x1+1)*y-x*y*2;
printf("%lld\n",ans);
}
}
}