【gdgzeroi】Problem C: 火神的鱼

题目描述:

火神最爱的就是吃鱼了,所以某一天他来到了一个池塘边捕鱼。池塘可以看成一个二维的平面,而他的渔网可以看成一个与坐标轴平行的矩形。

池塘里的鱼不停地在水中游动,可以看成一些点。有的时候会有鱼游进渔网,有的时候也会有鱼游出渔网。所以火神不知道什么时候收网才可以抓住最多的鱼,现在他寻求你的帮助。

他对池塘里的每条鱼都给予了一个标号,分别从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;
}

发布了703 篇原创文章 · 获赞 392 · 访问量 14万+

猜你喜欢

转载自blog.csdn.net/Eric1561759334/article/details/100386151