题目描述:
火神最爱的就是吃鱼了,所以某一天他来到了一个池塘边捕鱼。池塘可以看成一个二维的平面,而他的渔网可以看成一个与坐标轴平行的矩形。
池塘里的鱼不停地在水中游动,可以看成一些点。有的时候会有鱼游进渔网,有的时候也会有鱼游出渔网。所以火神不知道什么时候收网才可以抓住最多的鱼,现在他寻求你的帮助。
他对池塘里的每条鱼都给予了一个标号,分别从1到n标号,n表示池塘里鱼的总数。鱼的游动可以概括为两个动作:
1 l r d : 表示标号在[l,r]这个区间内的鱼向x轴正方向游动了d个单位长度。
2 l r d:表示标号在[l,r]这个区间内的鱼向y轴正方向游动了d个单位长度。
在某些时刻,火神会询问你现在有多少条鱼在渔网内(边界上的也算),请你来帮助他吧。
输入格式:
第一行包含一个整数T,表示测试数据组数。对于每组测试数据:
第一行包含一个整数n,表示鱼的总数。
第二行包含四个整数x1,y1,x2,y2,表示渔网的左下角坐标和右上角坐标。
接下来n行,每行两个整数xi,yi,表示标号为i的鱼初始时刻的坐标。
再接下来一行包含一个整数m,表示后面的事件数目。
再接下来的m行,每行为以下三种类型的一种:
1 l r d : 表示标号在[l,r]这个区间内的鱼向x轴正方向游动了d个单位长度。
2 l r d:表示标号在[l,r]这个区间内的鱼向y轴正方向游动了d个单位长度。
3 l r : 表示询问现在标号在[l,r]这个区间内的鱼有多少在渔网内。
输出格式:
对于每组数据的每个询问,输出一个整数表示对应的答案。
输入描述:
1
5
1 1 5 5
1 1
2 2
3 3
4 4
5 5
3
3 1 5
1 2 4 2
3 1 5
样例输出:
5
4
数据范围:
对于30%的数据满足:1≤n,m≤1000
对于100%的数据满足:1≤T≤10,1≤n,m≤30000,1≤l≤r≤n,1≤d≤109,x1≤x2,y1≤y2。保证任意时刻所有涉及的坐标值在[−109,109]范围内。
思路
代码
#include<bits/stdc++.h>
using namespace std;
#define y1 cxk
#define inf 2123333333
#define M 110000
struct tree { int num,x1,x2,y1,y2,tg1,tg2,l,r; }t[M*4];
struct node { int x,y; }a[M];
int tt,n,m,x1,y1,x2,y2;
void newnode(int x,int y){
t[x].num=(a[y].x>=x1&&a[y].x<=x2&&a[y].y>=y1&&a[y].y<=y2);
t[x].x1=t[x].x2=t[x].y1=t[x].y2=-inf;
if (a[y].x<x1) t[x].x1=a[y].x;
else if (a[y].x<=x2) t[x].x2=a[y].x;
if (a[y].y<y1) t[x].y1=a[y].y;
else if (a[y].y<=y2) t[x].y2=a[y].y;
}
void pushup(int x){
t[x].num=t[x<<1].num+t[x<<1|1].num;
t[x].x1=max(t[x<<1].x1,t[x<<1|1].x1);
t[x].x2=max(t[x<<1].x2,t[x<<1|1].x2);
t[x].y1=max(t[x<<1].y1,t[x<<1|1].y1);
t[x].y2=max(t[x<<1].y2,t[x<<1|1].y2);
}
void pushdown(int x){
if (t[x].tg1){
if (t[x<<1].x1!=-inf) t[x<<1].x1+=t[x].tg1;
if (t[x<<1|1].x1!=-inf) t[x<<1|1].x1+=t[x].tg1;
if (t[x<<1].x2!=-inf) t[x<<1].x2+=t[x].tg1;
if (t[x<<1|1].x2!=-inf) t[x<<1|1].x2+=t[x].tg1;
t[x<<1].tg1+=t[x].tg1;t[x<<1|1].tg1+=t[x].tg1;
t[x].tg1=0;
}
if (t[x].tg2){
if (t[x<<1].y1!=-inf) t[x<<1].y1+=t[x].tg2;
if (t[x<<1|1].y1!=-inf) t[x<<1|1].y1+=t[x].tg2;
if (t[x<<1].y2!=-inf) t[x<<1].y2+=t[x].tg2;
if (t[x<<1|1].y2!=-inf) t[x<<1|1].y2+=t[x].tg2;
t[x<<1].tg2+=t[x].tg2;t[x<<1|1].tg2+=t[x].tg2;
t[x].tg2=0;
}
}
void build(int x,int l,int r){
t[x].tg1=t[x].tg2=0;
t[x].l=l; t[x].r=r;
if (l==r) { newnode(x,l);return; }
int mid=(l+r)>>1;
build(x<<1,l,mid);
build(x<<1|1,mid+1,r);
pushup(x);
}
void modify1(int o,int x,int y,int hh){
if (t[o].l!=t[o].r) pushdown(o);
int mid=(t[o].l+t[o].r)>>1;
if (t[o].l>=x&&t[o].r<=y){
if (t[o].l==t[o].r){
if (t[o].x1==-inf&&t[o].x2==-inf) return;
if (t[o].x1!=-inf){
if (t[o].x1+hh<x1) t[o].x1+=hh;
else if (t[o].x1+hh<=x2){
t[o].x2=t[o].x1+hh;t[o].x1=-inf;
if (t[o].y2!=-inf) t[o].num=1;
}
else t[o].x1=-inf;
}
else{
if (t[o].x2+hh<=x2) t[o].x2+=hh;
else t[o].x2=-inf,t[o].num=0;
}
return;
}
if ((t[o].x2==-inf||t[o].x2+hh<=x2)&&(t[o].x1==-inf||t[o].x1+hh<x1)){
if (t[o].x1!=-inf) t[o].x1+=hh;
if (t[o].x2!=-inf) t[o].x2+=hh;
t[o].tg1+=hh;
return;
}
modify1(o<<1,x,y,hh);
modify1(o<<1|1,x,y,hh);
pushup(o);
}
else{
if (x<=mid) modify1(o<<1,x,y,hh);
if (y>mid) modify1(o<<1|1,x,y,hh);
pushup(o);
}
}
void modify2(int o,int x,int y,int hh){
if (t[o].l!=t[o].r) pushdown(o);
int mid=(t[o].l+t[o].r)>>1;
if (t[o].l>=x&&t[o].r<=y){
if (t[o].l==t[o].r){
if (t[o].y1==-inf&&t[o].y2==-inf) return;
if (t[o].y1!=-inf){
if (t[o].y1+hh<y1) t[o].y1+=hh;
else if (t[o].y1+hh<=y2){
t[o].y2=t[o].y1+hh;t[o].y1=-inf;
if (t[o].x2!=-inf) t[o].num=1;
}
else t[o].y1=-inf;
}
else{
if (t[o].y2+hh<=y2) t[o].y2+=hh;
else t[o].y2=-inf,t[o].num=0;
}
return;
}
if ((t[o].y2==-inf||t[o].y2+hh<=y2)&&(t[o].y1==-inf||t[o].y1+hh<y1)){
if (t[o].y1!=-inf) t[o].y1+=hh;
if (t[o].y2!=-inf) t[o].y2+=hh;
t[o].tg2+=hh;
return;
}
modify2(o<<1,x,y,hh);
modify2(o<<1|1,x,y,hh);
pushup(o);
}
else{
if (x<=mid) modify2(o<<1,x,y,hh);
if (y>mid) modify2(o<<1|1,x,y,hh);
pushup(o);
}
}
int query(int o,int l,int r){
if(l<=t[o].l&&t[o].r<=r) return t[o].num;
pushdown(o);
int mid=(t[o].l+t[o].r)>>1,res=0;
if (l<=mid) res+=query(o<<1,l,r);
if (r>mid) res+=query(o<<1|1,l,r);
return res;
}
int main()
{
int cas; cin>>cas; while(cas--){
cin>>n>>x1>>y1>>x2>>y2;
for (int i=1;i<=n;i++) scanf("%d%d",&a[i].x,&a[i].y);
build(1,1,n);
scanf("%d",&m); while (m--){
int p,x,y,z; scanf("%d%d%d",&p,&x,&y);
if (p==1) {scanf("%d",&z);modify1(1,x,y,z); }
else if (p==2) {scanf("%d",&z);modify2(1,x,y,z); }
else printf("%d\n",query(1,x,y));
}
}
return 0;
}