Tyvj1474 打鼹鼠

Description
在这个“打鼹鼠”的游戏中,鼹鼠会不时地从洞中钻出来,不过不会从洞口钻进去(鼹鼠真胆大……)。洞口都在一个大小为n(n<=1024)的正方形中。这个正方形在一个平面直角坐标系中,左下角为(0,0),右上角为(n-1,n-1)。洞口所在的位置都是整点,就是横纵坐标都为整数的点。而SuperBrother也不时地会想知道某一个范围的鼹鼠总数。这就是你的任务。

Input
每个输入文件有多行。
第一行,一个数n,表示鼹鼠的范围。
以后每一行开头都有一个数m,表示不同的操作:
m=1,那么后面跟着3个数x,y,k(0<=x,y<n),表示在点(x,y)处新出现了k只鼹鼠;
m=2,那么后面跟着4个数x1,y1,x2,y2(0<=x1<=x2<n,0<=y1<=y2<n),表示询问矩形(x1,y1)-(x2,y2)内的鼹鼠数量;
m=3,表示老师来了,不能玩了。保证这个数会在输入的最后一行。
询问数不会超过10000,鼹鼠数不会超过maxlongint。

Output
对于每个m=2,输出一行数,这行数只有一个数,即所询问的区域内鼹鼠的个数。

Sample Input
4
1 2 2 5
2 0 0 2 3
3

Sample Output
5

二维线段树板子题,其实二维线段树没那么高大上,维护一个以x排序的线段树,这棵线段树的每个节点都是维护以y排序的线段树,空间\(O(n^2)\),如果n大点就要用到类似主席树的动态开点技巧了

/*program from Wolfycz*/
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define inf 0x7f7f7f7f
using namespace std;
typedef long long ll;
typedef unsigned int ui;
typedef unsigned long long ull;
inline int read(){
    int x=0,f=1;char ch=getchar();
    for (;ch<'0'||ch>'9';ch=getchar())  if (ch=='-')    f=-1;
    for (;ch>='0'&&ch<='9';ch=getchar())    x=(x<<1)+(x<<3)+ch-'0';
    return x*f;
}
inline void print(int x){
    if (x>=10)     print(x/10);
    putchar(x%10+'0');
}
const int N=1024;
#define ls (p<<1)
#define rs (p<<1|1)
int n;
struct Segment{
    int tree[(N<<2)+10];
    void change(int p,int l,int r,int x,int v){
        if (l==r){
            tree[p]+=v;
            return;
        }
        int mid=(l+r)>>1;
        if (x<=mid) change(ls,l,mid,x,v);
        else    change(rs,mid+1,r,x,v);
        tree[p]=tree[ls]+tree[rs];
    }
    int Query(int p,int l,int r,int x,int y){
        if (x<=l&&r<=y) return tree[p];
        int mid=(l+r)>>1,res=0;
        if (x<=mid) res+=Query(ls,l,mid,x,y);
        if (y>mid)  res+=Query(rs,mid+1,r,x,y);
        return res;
    }
}T[(N<<2)+10];
void change(int p,int l,int r,int x,int y,int v){
    T[p].change(1,0,n,y,v);
    if (l==r)   return;
    int mid=(l+r)>>1;
    if (x<=mid) change(ls,l,mid,x,y,v);
    else    change(rs,mid+1,r,x,y,v);
}
int Query(int p,int l,int r,int x,int y,int X,int Y){
    if (x<=l&&r<=y) return T[p].Query(1,0,n,X,Y);
    int mid=(l+r)>>1,res=0;
    if (x<=mid) res+=Query(ls,l,mid,x,y,X,Y);
    if (y>mid)  res+=Query(rs,mid+1,r,x,y,X,Y);
    return res;
}
int main(){
    n=read();
    while (true){
        int t=read();
        if (t==1){
            int x=read(),y=read(),k=read();
            change(1,0,n,x,y,k);
        }
        if (t==2){
            int ox=read(),oy=read(),ex=read(),ey=read();
            printf("%d\n",Query(1,0,n,ox,ex,oy,ey));
        }
        if (t==3)   break;
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/Wolfycz/p/9465539.html
今日推荐