1. 程式人生 > >Tyvj1474 打鼴鼠

Tyvj1474 打鼴鼠

typedef void inf 範圍 include 二維線段樹 區域 NPU getch

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;
}

Tyvj1474 打鼴鼠