cogs577

577. 蝗灾

输入文件:locust.in 输出文件:locust.out 简单对比

时间限制:2 s 内存限制:128 MiB

【题目描述】

C国国土辽阔,地大物博......但是最近却在闹蝗灾.....
我们可以把C国国土当成一个W×W的矩阵,你会收到一些诸如(X,Y,Z)的信息,代表(X,Y)这个点增多了Z只蝗虫,而由于C国政府机关比较臃肿,为了批复消灭蝗虫的请求需要询问一大堆的问题......每个询问形如(X1,Y1,X2,Y2),询问在(X1,Y1,X2,Y2)范围内有多少蝗虫(请注意询问不会改变区域内的蝗虫数),你作为一个C国的程序员,需要编一个程序快速的回答所有的询问。

NOTICE
C国一开始没有蝗虫。

【输入格式】

输入文件的第一行包括一个整数W,代表C国国土的大小。
第二行有一个整数N,表示事件数。
接下来有N行表示N个事件,以(1 X Y Z)的形式或(2,X1,Y1,X2,Y2)的形式给出,分别代表蝗虫的增加和询问。

【输出格式】

对于每个询问输出一个整数表示需要的结果。

【样例输入】

5
8
2 4 1 4 2
1 3 1 8
1 4 4 4
2 1 3 4 4
1 1 5 1
1 4 4 5
2 2 2 5 4
2 3 2 4 4

【样例输出】

0
4
9
9

【数据范围】

10%的数据满足W<=100,N<=100;
30%的数据满足W<=2000,N<=5000;
50%的数据满足W<=100000,N<=50000;
100%的数据满足W<=500000,N<=200000,每次蝗虫增加数不超过1000;


三维偏序问题的变形,实际上也没变形!
CDQ分治的模板题


#include<bits/stdc++.h>
using namespace std;
const int maxn=2e5+10;
const int maxm=5e5+10;
struct node
{
    int x,y,z,t,type;
    //type:类型,1修改,2查询减,3查询加
    //t:时间
    //z:修改时为增加的值,查询是为查询的序号
    bool operator < (const node & a ) const 
    {
        if(x!=a.x)return x<a.x;
        if(y!=a.y)return y<a.y;
        if(t!=a.t)return t<a.t;
        return 0;
    }
}sz[maxn<<2],f[maxn<<2];
int w,n;
int ans[maxn];
int sum[maxm];
void add(int pos,int x)
{
    for(int i=pos;i<=w;i+=(-i)&i)sum[i]+=x;
}
int query(int pos)
{
    int ret=0;
    for(int i=pos;i;i-=(-i)&i)ret+=sum[i];
    return ret;
}
void cdq(int l,int r)
{
    if(l==r)return;
    int mid=(l+r)>>1;
    cdq(l,mid);
    cdq(mid+1,r);
    int q=l,h=mid+1,p=l;
    while(q<=mid&&h<=r)
    {
        if(sz[q]<sz[h])
        {
            f[p]=sz[q];
            if(sz[q].type==1)add(sz[q].y,sz[q].z);
            ++p;++q;
        }
        else
        {
            f[p]=sz[h];
            if(sz[h].type!=1)
            {
                int tp=query(sz[h].y);
                if(sz[h].type==2)ans[sz[h].z]-=tp;
                else ans[sz[h].z]+=tp;
            }
            ++p;++h;
        }
    }
    while(q<=mid)
    {
        f[p]=sz[q];
        if(sz[q].type==1)add(sz[q].y,sz[q].z);
        ++p;++q;
    }
    while(h<=r)
    {
        f[p]=sz[h];
        if(sz[h].type!=1)
        {
            int tp=query(sz[h].y);
            if(sz[h].type==2)ans[sz[h].z]-=tp;
            else ans[sz[h].z]+=tp;
        }
        ++p;++h;
    }
    for(int i=l;i<=mid;++i)if(sz[i].type==1)add(sz[i].y,-sz[i].z);
    for(int i=l;i<=r;++i)sz[i]=f[i];
}
int main()
{
    freopen("locust.in","r",stdin);
    freopen("locust.out","w",stdout);
    int tim=0,cnt=0;;
    scanf("%d%d",&w,&n);
    for(int op,a,b,c,d,i=1;i<=n;++i)
    {
        scanf("%d",&op);
        if(op==1)
        {
            scanf("%d%d%d",&a,&b,&c);
            ++tim;
            sz[tim].x=a;sz[tim].y=b;sz[tim].z=c;sz[tim].t=tim;
            sz[tim].type=1;
        }
        else
        {
            scanf("%d%d%d%d",&a,&b,&c,&d);
            ++cnt;
            ++tim;
            sz[tim].x=c;sz[tim].y=d;sz[tim].z=cnt;sz[tim].type=3;sz[tim].t=tim;
            ++tim;
            sz[tim].x=a-1;sz[tim].y=b-1;sz[tim].z=cnt;sz[tim].type=3;sz[tim].t=tim;
            ++tim;
            sz[tim].x=c;sz[tim].y=b-1;sz[tim].z=cnt;sz[tim].type=2;sz[tim].t=tim;
            ++tim;
            sz[tim].x=a-1;sz[tim].y=d;sz[tim].z=cnt;sz[tim].type=2;sz[tim].t=tim;
        }
    }
    cdq(1,tim);
    for(int i=1;i<=cnt;++i)printf("%d\n",ans[i]);
    return 0;
}
/*
5
8
2 4 1 4 2
1 3 1 8
1 4 4 4
2 1 3 4 4
1 1 5 1
1 4 4 5
2 2 2 5 4
2 3 2 4 4

0
4
9
9
*/

posted on 2021-11-02 17:00  gryzy  阅读(18)  评论(0编辑  收藏  举报

导航