zoukankan      html  css  js  c++  java
  • COJ1012 WZJ的数据结构(十二)

    今天突然想写个树套树爽一爽(1810ms)

    写的是树状数组套线段树(动态开节点)

    #include<cstdio>
    #include<cctype>
    #include<cstring>
    #include<algorithm>
    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;
    const int maxnode=20000010;
    int sum[maxnode],ls[maxnode],rs[maxnode],ToT;
    void update(int& y,int l,int r,int& pos,int& v)
    {
        if(!y) y=++ToT;
        sum[y]+=v;if(l==r) return;
        int mid=l+r>>1;
        if(pos<=mid) update(ls[y],l,mid,pos,v);
        else update(rs[y],mid+1,r,pos,v);
    }
    int ans;
    void query(int& y,int l,int r,int& ql,int& qr)
    {
        if(ql<=l&&r<=qr) {ans+=sum[y];return;}
        if(!y) return;
        int mid=l+r>>1;
        if(ql<=mid) query(ls[y],l,mid,ql,qr);
        if(qr>mid) query(rs[y],mid+1,r,ql,qr);
    }
    int n,root[maxn],lastans;
    void add(int x,int y,int v)
    {
        for(;x<=400000;x+=x&-x) update(root[x],1,400000,y,v);
    }
    int query(int x,int ql,int qr)
    {
        ans=0;
        for(;x;x-=x&-x) query(root[x],1,400000,ql,qr);
        return ans;
    }
    int tp[200010],x1[200010],x2[200010],y1[200010],y2[200010],v[200010];
    int tmp[400010],tot;
    int main()
    {
        read();n=read();int m;
        for(int i=1;;i++)
        {
            tp[i]=read();
            if(tp[i]==3) {m=i;break;}
            else if(tp[i]==1) x1[i]=read(),y1[i]=read(),v[i]=read();
            else x1[i]=read(),y1[i]=read(),x2[i]=read(),y2[i]=read(),tmp[++tot]=x2[i];
            tmp[++tot]=x1[i];
        }
        sort(tmp+1,tmp+tot+1);
        for(int i=1;i<=m;i++) x1[i]=lower_bound(tmp+1,tmp+tot+1,x1[i])-tmp,x2[i]=lower_bound(tmp+1,tmp+tot+1,x2[i])-tmp;
        tot=0;for(int i=1;i<=m;i++) tmp[++tot]=y1[i],tmp[++tot]=y2[i];sort(tmp+1,tmp+tot+1);
        for(int i=1;i<=m;i++) y1[i]=lower_bound(tmp+1,tmp+tot+1,y1[i])-tmp,y2[i]=lower_bound(tmp+1,tmp+tot+1,y2[i])-tmp;
        for(int i=1;i<=m;i++)
        {
            if(tp[i]==3) break;
            else if(tp[i]==1) add(x1[i],y1[i],v[i]);
            else printf("%d
    ",query(x2[i],y1[i],y2[i])-query(x1[i]-1,y1[i],y2[i]));
        }
        return 0;
    }
    View Code

    竟然还要离散TAT(maxnode开到2*10^8会RE,开到2.5*10^8会MLE)

    这是之前写的CDQ分治(328ms)

    代码难看勿喷

    #include<cstdio>
    #include<cstring>
    #include<cctype>
    #include<algorithm>
    using namespace std;
    char ch;int sig;
    inline void read(int& x)
    {
        ch=getchar(); sig=1; x=0;
        while(!isdigit(ch)&&ch!='-') ch=getchar();
        if(ch=='-') sig=-1,ch=getchar();
        while(isdigit(ch)) x=x*10+ch-'0',ch=getchar();
        x*=sig;
    }
    const int maxn=250010;
    struct Query
    {
        int t,x,y,v,id;
        bool operator < (const Query& ths) const
        {
            return x<ths.x||(x==ths.x&&y<ths.y)||(x==ths.x&&y==ths.y&&t<ths.t);
        }
    }A[maxn],t1[maxn];
    int ans[10010];
    int w,s;
    int C[2000010];
    void update(int x,int v)
    {
        for(;x<=w;x+=x&-x) C[x]+=v;
    }
    int query(int x)
    {
        int ret=0;
        for(;x;x-=x&-x) ret+=C[x];
        return ret;
    }
    void solve(int L,int R)
    {
        if(L==R) return;
        int m1=0,m2=0,M=L+R>>1;
        solve(L,M);
        solve(M+1,R);
        for(int i=L;i<=M;i++) if(A[i].t==1) t1[m1++]=A[i];
        if(!m1) return;
        m2=m1;
        for(int i=M+1;i<=R;i++) if(A[i].t==2) t1[m2++]=A[i];
        if(m2==m1) return;
        sort(t1,t1+m2);
        for(int i=0;i<m2;i++)
        {
            if(t1[i].t==1) update(t1[i].y,t1[i].v);
            else ans[t1[i].id]+=t1[i].v*query(t1[i].y);
        }
        for(int i=0;i<m2;i++) if(t1[i].t==1) update(t1[i].y,-t1[i].v);
    }
    int main()
    {
        scanf("%d%d",&s,&w);
        int x1,y1,x2,y2,t,a,tot=0,n=0;
        while(1)
        {
            read(t);
            if(t==3) break;
            if(t==1)
            {
                read(x1); read(y1); read(a);
                A[++tot]=(Query){t,x1,y1,a,1};
            }
            else
            {
                read(x1); read(y1); read(x2); read(y2);
                ans[++n]=(x2-x1+1)*(y2-y1+1)*s;
                A[++tot]=(Query){t,x1-1,y1-1,1,n};
                A[++tot]=(Query){t,x2,y2,1,n};
                A[++tot]=(Query){t,x1-1,y2,-1,n};
                A[++tot]=(Query){t,x2,y1-1,-1,n};
            }
        }
        solve(1,tot);
        for(int i=1;i<=n;i++) printf("%d
    ",ans[i]);
        return 0;
    }
    View Code

     YY了一个k-d树(625ms)

    #include<cstdio>
    #include<cctype>
    #include<cstring>
    #include<algorithm>
    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=500010;
    int lc[maxn],rc[maxn],x[maxn],y[maxn],mxx[maxn],mxy[maxn],mnx[maxn],mny[maxn],sum[maxn];
    void maintain(int r)
    {
        mxx[r]=max(x[r],max(mxx[lc[r]],mxx[rc[r]]));
        mnx[r]=min(x[r],min(mnx[lc[r]],mnx[rc[r]]));
        mxy[r]=max(y[r],max(mxy[lc[r]],mxy[rc[r]]));
        mny[r]=min(y[r],min(mny[lc[r]],mny[rc[r]]));
    }
    int x1,y1,x2,y2,v,ToT;
    void insert(int& r,int d)
    {
        if(!r) r=++ToT,x[r]=mxx[r]=mnx[r]=x1,y[r]=mny[r]=mxy[r]=y1;
        sum[r]+=v;
        if(x[r]==x1&&y[r]==y1) return;
        if(!d) 
        {
            if(x1<=x[r]) insert(lc[r],d^1);
            else insert(rc[r],d^1);
        }
        else
        {
            if(y1<=y[r]) insert(lc[r],d^1);
            else insert(rc[r],d^1);
        }
        maintain(r);
    }
    int query(int r,int d)
    {
        if(!r) return 0;
        if(mnx[r]>=x1&&mxx[r]<=x2&&mny[r]>=y1&&mxy[r]<=y2) return sum[r];
        int ret=0;
        if(x[r]<=x2&&x[r]>=x1&&y[r]<=y2&&y[r]>=y1) ret+=sum[r]-sum[lc[r]]-sum[rc[r]];
        if(!d)
        {
            if(x1<=x[r]) ret+=query(lc[r],d^1);
            if(x2>x[r]) ret+=query(rc[r],d^1);
        }
        else
        {
            if(y1<=y[r]) ret+=query(lc[r],d^1);
            if(y2>y[r]) ret+=query(rc[r],d^1);
        }
        return ret;
    }
    int main()
    {
        read();int n=read(),root=0;
        mxx[0]=mxy[0]=-1e9;mnx[0]=mny[0]=1e9;
        for(;;)
        {
            int tp=read();
            if(tp==3) break;
            else if(tp==1)
            {
                x1=read();y1=read();v=read();
                insert(root,0);
            }
            else
            {
                x1=read();y1=read();x2=read();y2=read();
                printf("%d
    ",query(root,0));
            }
        }
        return 0;
    }
    View Code

     最后写了写树状数组套Treap(1919ms)

    #include<cstdio>
    #include<cctype>
    #include<cstring>
    #include<ctime>
    #include<algorithm>
    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=2000010;
    struct Node
    {
        Node* ch[2];
        int r,s,v,v2,sum;
        void maintain() {s=ch[0]->s+ch[1]->s+1;sum=v2+ch[0]->sum+ch[1]->sum;}
    }nodes[maxn],*null=&nodes[0];
    int ToT;
    void rotate(Node* &o,int d)
    {
        Node* k=o->ch[d^1];o->ch[d^1]=k->ch[d];k->ch[d]=o;
        o->maintain();k->maintain();o=k;
    }
    void insert(Node* &o,int v,int v2)
    {
        if(o==null) 
        {
            o=&nodes[++ToT];
            o->r=rand();o->s=1;o->v=v;o->v2=o->sum=v2;
            o->ch[0]=o->ch[1]=null;
        }
        else 
        {
            int d=v>o->v;
            insert(o->ch[d],v,v2);
            if(o->ch[d]->r>o->r) rotate(o,d^1);
            else o->maintain();
        }
    }
    int query(Node* &o,int v)
    {
        if(o==null) return 0;
        if(v<=o->v) return query(o->ch[0],v);
        return o->ch[0]->sum+o->v2+query(o->ch[1],v);
    }
    Node* root[maxn];int n;
    void add(int x,int y,int v)
    {
        for(;x<=n;x+=x&-x) insert(root[x],y,v);
    }
    int query(int x,int y1,int y2)
    {
        int ret=0;
        for(;x;x-=x&-x) ret+=query(root[x],y2+1)-query(root[x],y1);
        return ret;
    }
    int main()
    {
        srand(time(0));null->s=null->sum=0;
        read();n=read();
        for(int i=1;i<=n;i++) root[i]=null;
        for(;;)
        {
            int tp=read();
            if(tp==3) break;
            if(tp==1)
            {
                int x=read(),y=read(),v=read();
                add(x,y,v);
            }
            else
            {
                int x1=read(),y1=read(),x2=read(),y2=read();
                printf("%d
    ",query(x2,y1,y2)-query(x1-1,y1,y2));
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    RECOVER DATABASE SKIP TABLESPACE
    mysql加解密函数
    node获取代码的svn版本号,并打包的时候,输出指定文件到打包后的项目里面
    layer.open iframe自动高度
    IIS部署.net5项目
    使用Windows命令行启动关闭服务(net,sc用法)(转)
    centos7 修改IP 设置静态IP,开启SSH
    链接PostgreSQL报错authentication method 10 not supported解决
    PostgreSQL Windows安装教程
    POI隐藏行 隐藏列,EasyExcel隐藏行 EasyExcel隐藏列
  • 原文地址:https://www.cnblogs.com/wzj-is-a-juruo/p/4516927.html
Copyright © 2011-2022 走看看