BZOJ4066 簡單題

來源:互聯網
上載者:User

標籤:

Description

你有一個N*N的棋盤,每個格子內有一個整數,初始時的時候全部為0,現在需要維護兩種操作:

命令 參數限制 內容
1 x y A 1<=x,y<=N,A是正整數 將格子x,y裡的數字加上A
2 x1 y1 x2 y2 1<=x1<= x2<=N

 

1<=y1<= y2<=N

輸出x1 y1 x2 y2這個矩形內的數字和
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

新加資料一組,但未重測—-2015.05.24

 

我終於過了!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

由於記憶體很緊,我們不能用樹套樹來做,但k-d樹還是可以的。

考慮出題人可能將k-d樹的形態搞得很糟糕,我們可以定期重建整棵樹

#include<cstdio>#include<cctype>#include<queue>#include<cstring>#include<algorithm>#define rep(s,t) for(int i=s;i<=t;i++)#define ren for(int i=first[x];i!=-1;i=next[i])using namespace std;inline int read() {    int x=0,f=1;char c=getchar();    for(;!isdigit(c);c=getchar()) if(c==‘-‘) f=-1;    for(;isdigit(c);c=getchar()) x=x*10+c-‘0‘;    return x*f;}const int maxn=200010;int n,D,lastans;struct Point {    int d[2],mx[2],mn[2],v,l,r,sum;    bool operator == (const Point& ths) const {return d[0]==ths.d[0]&&d[1]==ths.d[1];}    bool operator < (const Point& ths) const {return d[D]<ths.d[D];}}p[maxn];int in(int& x1,int& y1,int& x2,int& y2,int& X1,int& Y1,int& X2,int& Y2) {return x1<=X1&&x2>=X2&&y1<=Y1&&y2>=Y2;}int out(int& x1,int& y1,int& x2,int& y2,int& X1,int& Y1,int& X2,int& Y2) {return x1>X2||x2<X1||y1>Y2||y2<Y1;}struct Kd_Tree {    Point t[maxn],now;    int rt,cnt;    Kd_Tree() {t[0].mn[0]=t[0].mn[1]=2e9;t[0].mx[0]=t[0].mx[1]=-2e9;}    void maintain(int k) {        int l=t[k].l,r=t[k].r;        rep(0,1) t[k].mn[i]=min(t[k].d[i],min(t[l].mn[i],t[r].mn[i])),t[k].mx[i]=max(t[k].d[i],max(t[l].mx[i],t[r].mx[i]));        t[k].sum=t[l].sum+t[r].sum+t[k].v;    }    void insert(int& k,int d) {        if(!k) k=++cnt,t[k].d[0]=t[k].mx[0]=t[k].mn[0]=now.d[0],t[k].d[1]=t[k].mx[1]=t[k].mn[1]=now.d[1];        if(now==t[k]) {            t[k].v+=now.v;t[k].sum+=now.v;            return;        }        if(now.d[d]<t[k].d[d]) insert(t[k].l,d^1);        else insert(t[k].r,d^1);        maintain(k);    }    int query(int k,int x1,int y1,int x2,int y2) {        if(!k) return 0;        if(in(x1,y1,x2,y2,t[k].mn[0],t[k].mn[1],t[k].mx[0],t[k].mx[1])) return t[k].sum;        if(out(x1,y1,x2,y2,t[k].mn[0],t[k].mn[1],t[k].mx[0],t[k].mx[1])) return 0;        int ret=0;        if(in(x1,y1,x2,y2,t[k].d[0],t[k].d[1],t[k].d[0],t[k].d[1])) ret+=t[k].v;        ret+=query(t[k].l,x1,y1,x2,y2)+query(t[k].r,x1,y1,x2,y2);        return ret;    }    int build(int l,int r,int d) {        if(l>r) return 0;        int mid=l+r>>1;D=d;nth_element(p+l,p+mid,p+r+1);        t[mid]=p[mid];t[mid].l=build(l,mid-1,d^1);t[mid].r=build(mid+1,r,d^1);        maintain(mid);return mid;    }}T;int main() {    n=read();int ToT=0;    while(1) {        int tp=read();        if(tp==3) break;        else if(tp==1) {            int x=read()^lastans,y=read()^lastans;            T.now.d[0]=x;T.now.d[1]=y;            T.now.v=T.now.sum=read()^lastans;            T.insert(T.rt,0);            if(++ToT==7000) {                rep(1,T.cnt) p[i]=T.t[i];                T.rt=T.build(1,T.cnt,0);ToT=0;            }        }        else {            int x=read()^lastans,y=read()^lastans,x2=read()^lastans,y2=read()^lastans;            printf("%d\n",lastans=T.query(T.rt,x,y,x2,y2));        }    }    return 0;}
View Code

 

BZOJ4066 簡單題

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.