zoukankan      html  css  js  c++  java
  • bzoj4066 简单题

    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操作,输出一个对应的答案。

    k-d树维护插入和查询,每插入一定次数重构整棵树

    #include<cstdio>
    #include<algorithm>
    int X[2],A,la=0;
    int mns[2],mxs[2],x0,x1,y0,y1;
    inline void mins(int&x,int y){if(x>y)x=y;}
    inline void maxs(int&x,int y){if(x<y)x=y;}
    int read(){
        int x=0,c=getchar();
        while(c<'0'||c>'9')c=getchar();
        while(c>='0'&&c<='9')x=x*10+c-'0',c=getchar();
        return x;
    }
    struct node{
        int m[2];
        int mn[2],mx[2];
        int v,s,c[2];
        void set(){
            for(int i=0;i<2;i++)m[i]=mn[i]=mx[i]=X[i];
            v=s=A;
            c[0]=c[1]=0;
        }
    };
    struct pos{
        int x,y,v;
    };
    int d_x=0;
    bool operator<(pos a,pos b){
        if(d_x)return a.y<b.y;
        else return a.x<b.x;
    }
    int op;
    node ns[200005];
    pos ps[200005];
    int np=1,pp=0;
    void upd(int ww){
        node&w=ns[ww];
        w.s=w.v;
        for(int i=0;i<2;i++){
            if(w.c[i]){
                node&u=ns[w.c[i]];
                w.s+=u.s;
                for(int j=0;j<2;j++)
                    mins(w.mn[j],u.mn[j]),
                    maxs(w.mx[j],u.mx[j]);
            }
        }
    }
    void insert(int ww,int dx){
        node&w=ns[ww];
        bool f=X[dx]<w.m[dx];
        if(w.c[f])insert(w.c[f],dx^1);
        else w.c[f]=np++;
        upd(ww);
    }
    void ins(){
        if(np>1)insert(1,0);
        else np++;
    }
    int build(int l,int r,int d){
        d_x=d;
        int m=l+r>>1;
        std::nth_element(ps+l,ps+m,ps+r);
        int ww=np++;
        node&w=ns[ww];
        X[0]=ps[m].x,X[1]=ps[m].y,A=ps[m].v;
        w.set();
        if(l<m)w.c[0]=build(l,m,d^1);
        else w.c[0]=0;
        if(m+1<r)w.c[1]=build(m+1,r,d^1);
        else w.c[1]=0;
        upd(ww);
        return ww;
    }
    void rebuild(){
        np=1;
        build(0,pp,0);
    }
    int ask(int ww=1){
        if(!ww)return 0;
        node&w=ns[ww];
        if(x0<=w.mn[0]&&w.mx[0]<=x1&&y0<=w.mn[1]&&w.mx[1]<=y1)return w.s;
        if(x0>w.mx[0]||x1<w.mn[0]||y0>w.mx[1]||y1<w.mn[1])return 0;
        int a=0;
        if(x0<=w.m[0]&&w.m[0]<=x1&&y0<=w.m[1]&&w.m[1]<=y1)a=w.v;
        for(int i=0;i<2;i++)a+=ask(w.c[i]);
        return a;
    }
    int t=0;
    int main(){
        read();
        while(1){
            op=read();
            if(op==3)break;
            if(op==1){
                ps[pp].x=X[0]=read()^la;
                ps[pp].y=X[1]=read()^la;
                ps[pp++].v=A=read()^la;
                ns[np].set();
                ins();
                t++;
                if(t>10000)rebuild(),t=0;
            }else{
                x0=mns[0]=read()^la;
                y0=mns[1]=read()^la;
                x1=mxs[0]=read()^la;
                y1=mxs[1]=read()^la;
                printf("%d
    ",la=ask());
            }
        }
        return 0;
    }
  • 相关阅读:
    jQuery对表单的操作
    js-工厂模式
    js中call、apply、bind的区别
    js实现重载和重写
    js封装/继承/多态
    变量的解构赋值
    var & let & const 的区别
    jQuery之animate中的queue
    jQuery之动画
    .trigger
  • 原文地址:https://www.cnblogs.com/ccz181078/p/5148169.html
Copyright © 2011-2022 走看看