zoukankan      html  css  js  c++  java
  • UOJ 218 火车管理

    http://uoj.ac/problem/218

    思路:建立一个可持久化线段树,代表这个位置的火车是哪辆,然后再弄一个线段树维护答案。

    如果询问,直接询问线段树。

    如果区间压入,直接在主席树上面压入,然后更新线段树答案

    如果弹出,那么直接找主席树当前位之前的火车是那辆,然后修改线段树答案,再修改当前主席树答案。

    改题的时候蜜汁错误。。

    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    int tr[40000005],ls[40000005],tag[40000005],rs[40000005];
    int tg[2000005],sum[2000005],sz,rt[500005],a[500005];
    int n,m,ty;
    int read(){
        int t=0,f=1;char ch=getchar();
        while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
        while ('0'<=ch&&ch<='9'){t=t*10+ch-'0';ch=getchar();}
        return t*f;
    }
    void pushdown(int k){
        if (tag[k]==-1) return;
        if (!ls[k]) ls[k]=++sz;
        if (!rs[k]) rs[k]=++sz;
        tag[ls[k]]=tag[rs[k]]=tr[ls[k]]=tr[rs[k]]=tag[k];
        tag[k]=-1;
    }
    void add(int &k,int kk,int l,int r,int x,int y,int v){
        k=++sz;tag[k]=-1;
        if (x==l&&r==y){
            tag[k]=tr[k]=v;
            return;
        }
        pushdown(kk);
        int mid=(l+r)>>1;
        ls[k]=ls[kk];rs[k]=rs[kk];
        if (y<=mid) add(ls[k],ls[kk],l,mid,x,y,v);
        else
        if (x>mid) add(rs[k],rs[kk],mid+1,r,x,y,v);
        else 
        add(ls[k],ls[kk],l,mid,x,mid,v),add(rs[k],rs[kk],mid+1,r,mid+1,y,v);
    }
    int query(int k,int l,int r,int pos){
        if (!k||l==r) return tr[k];
        pushdown(k);
        int mid=(l+r)>>1;
        if (pos<=mid) return query(ls[k],l,mid,pos);
        else return query(rs[k],mid+1,r,pos);
    }
    void pushdown(int k,int l,int r){
        if (tg[k]==-1||l==r) return;
        tg[k*2]=tg[k*2+1]=tg[k];
        int mid=(l+r)>>1;
        sum[k*2]=tg[k]*(mid-l+1);
        sum[k*2+1]=tg[k]*(r-mid);
        tg[k]=-1;
    }
    void modify(int k,int l,int r,int x,int y,int v){
        pushdown(k,l,r);
        if (x==l&&r==y){
            tg[k]=v;sum[k]=(r-l+1)*v;
            pushdown(k,l,r);
            return;
        }
        int mid=(l+r)>>1;
        if (y<=mid) modify(k*2,l,mid,x,y,v);
        else
        if (x>mid) modify(k*2+1,mid+1,r,x,y,v);
        else modify(k*2,l,mid,x,mid,v),modify(k*2+1,mid+1,r,mid+1,y,v);
        sum[k]=sum[k*2]+sum[k*2+1]; 
    }
    int getsum(int k,int l,int r,int x,int y){
        pushdown(k,l,r);
        if (x==l&&r==y){
            return sum[k];
        }
        int mid=(l+r)>>1,z=0;
        if (y<=mid) return getsum(k*2,l,mid,x,y);
        else
        if (x>mid) return getsum(k*2+1,mid+1,r,x,y);
        else return getsum(k*2,l,mid,x,mid)+getsum(k*2+1,mid+1,r,mid+1,y);
    }
    int main(){
        n=read();m=read();ty=read();
        int ans=0;
        for (int i=1;i<=m;i++){
            rt[i]=rt[i-1];
            int opt=read(),l=read();l=(l+ty*ans)%n+1;
            if (opt==2){
                int x=query(rt[i],1,n,l);
                if (x){
                    int y=query(rt[x-1],1,n,l);
                    add(rt[i],rt[i],1,n,l,l,y);
                    modify(1,1,n,l,l,a[y]);
                }
                continue;
            }
            int r=read();r=(r+ty*ans)%n+1;
            if (l>r) std::swap(l,r);
            if (opt==1){printf("%d
    ",ans=getsum(1,1,n,l,r));}
            else{
               a[i]=read();
               add(rt[i],rt[i],1,n,l,r,i);
               modify(1,1,n,l,r,a[i]);    
            }
        }
        return 0;
    }
  • 相关阅读:
    【原创】使用开源libimobiledevice盗取iphone信息
    【原创】Arduino制作Badusb实践
    【原创】Aduino小车玩法全记录
    【原创】Arduino入门基础知识总结
    【原创】Arduino、arm、树莓派与单片机
    【原创】PM3破解IC卡记录
    【转】反编译D-Link路由器固件程序并发现后门
    DDOS分布式拒绝服务
    XSS 初识
    针对企业级别渗透测试流程
  • 原文地址:https://www.cnblogs.com/qzqzgfy/p/5685930.html
Copyright © 2011-2022 走看看