bzoj 4066: 簡單題 kd-tree

4066: 簡單題

Time Limit: 50 Sec  Memory Limit: 20 MB
Submit: 234  Solved: 82
[ Submit][ Status][ Discuss]

Description

你有一個N*N的棋盤,每一個格子內有一個整數,初始時的時候所有爲0,如今須要維護兩種操做:

 

命令php

參數限制node

內容ios

1 x y Aspa

1<=x,y<=N,A是正整數code

將格子x,y裏的數字加上Ablog

2 x1 y1 x2 y2ip

1<=x1<= x2<=N內存

1<=y1<= y2<=Nci

輸出x1 y1 x2 y2這個矩形內的數字和get

3

終止程序

Input

輸入文件第一行一個正整數N。
接下來每行一個操做。每條命令除第一個數字以外,
均要異或上一次輸出的答案last_ans,初始時last_ans=0。

Output

對於每一個2操做,輸出一個對應的答案。

Sample Input

4
1 2 3 3
2 1 1 3 3
1 1 1 1
2 1 1 0 7
3

Sample Output

3
5

HINT

數據規模和約定

 

1<=N<=500000,操做數不超過200000個,內存限制20M,保證答案在int範圍內而且解碼以後數據仍合法。

 

樣例解釋見OJ2683
 
kd-tree (不須要套替罪羊)不用解釋了吧。。。。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
#define MAXN 300100
#define MAXT MAXN
#define INF 0x3f3f3f3f
struct kdt_node
{
        int lc,rc;
        int xmn,xmx;
        int ymn,ymx;
        int sum;
        int x,y;
}kdt[MAXT];
int topt=0;
inline void update(int now)
{
        kdt[now].xmn=min(kdt[now].x,min(kdt[kdt[now].lc].xmn,kdt[kdt[now].rc].xmn));
        kdt[now].xmx=max(kdt[now].x,max(kdt[kdt[now].lc].xmx,kdt[kdt[now].rc].xmx));
        kdt[now].ymn=min(kdt[now].y,min(kdt[kdt[now].lc].ymn,kdt[kdt[now].rc].ymn));
        kdt[now].ymx=max(kdt[now].y,max(kdt[kdt[now].lc].ymx,kdt[kdt[now].rc].ymx));
}
int x,y,v;
void Add_kdt(int &now,int d=0)
{
        if (!now)
        {
                now=++topt;
                kdt[now].x=x;
                kdt[now].y=y;
                update(now);
        }
        kdt[now].sum+=v;
        if (kdt[now].x==x && kdt[now].y==y)return ;
        if (!d)
        {
                if (x<=kdt[now].x)
                {
                        Add_kdt(kdt[now].lc,1-d);
                }else
                {
                        Add_kdt(kdt[now].rc,1-d);
                }
        }else
        {
                if (y<=kdt[now].y)
                {
                        Add_kdt(kdt[now].lc,1-d);
                }else
                {
                        Add_kdt(kdt[now].rc,1-d);
                }
        }
        update(now);
}
int x1,x2,y1,y2;
int Query_kdt(int now,int d)
{
        if (!now)return 0;
        if (kdt[now].xmn>=x1 && kdt[now].xmx<=x2 && kdt[now].ymn>=y1 && kdt[now].ymx<=y2)
                return kdt[now].sum;
        int ret=0;
        if (kdt[now].x<=x2 && kdt[now].x>=x1 && kdt[now].y<=y2 && kdt[now].y>=y1)ret+=kdt[now].sum-kdt[kdt[now].lc].sum-kdt[kdt[now].rc].sum;
        if (!d)
        {
                if (x1<=kdt[now].x)
                        ret+=Query_kdt(kdt[now].lc,1-d);
                if (x2>kdt[now].x)
                        ret+=Query_kdt(kdt[now].rc,1-d);
        }else
        {
                if (y1<=kdt[now].y)
                        ret+=Query_kdt(kdt[now].lc,1-d);
                if (y2>kdt[now].y)
                        ret+=Query_kdt(kdt[now].rc,1-d);
        }
        return ret;
}
 
 
int main()
{
    //  freopen("input.txt","r",stdin);
    //  freopen("output.txt","w",stdout);
        int n,m;
        scanf("%d",&n);
        int root=0;
        int opt=0;
        int lastans=0;
        kdt[0].xmn=kdt[0].ymn=INF;
        kdt[0].xmx=kdt[0].ymx=-INF;
        while (true)
        {
                scanf("%d",&opt);
                if (opt==1)
                {
                        scanf("%d%d%d",&x,&y,&v);
                        x^=lastans;y^=lastans;v^=lastans;
                        Add_kdt(root,0);
                }else if (opt==2)
                {
                        scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
                        x1^=lastans;x2^=lastans;y1^=lastans;y2^=lastans;
                        printf("%d\n",lastans=Query_kdt(root,0));
                }else
                {
                        break;
                }
        }
}
相關文章
相關標籤/搜索