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\n",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;
}

 

posted @ 2016-07-19 19:13  GFY  阅读(589)  评论(0编辑  收藏  举报