• 【UOJ UNR #1】火车管理


    来自FallDream的博客,未经允许,请勿转载,谢谢。


    题面

    考虑用可持久化线段树直接维护每个点在不同时刻,第一辆车的编号。

    这样3操作就变成了区间赋值,1操作变成区间和

    2操作的话,只需要查询一下现在这辆车的编号,再到历史版本去查一下上一辆车的编号就行了。

    #include<iostream>
    #include<cstdio>
    #define MN 500000
    using namespace std;
    inline int read()
    {
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    int n,m,ty,rt[MN+5],cnt=0,num[MN+5];
    struct Tree{
        int l,r,sum,val;
    }T[MN*131];
    inline int newnode(int x,int flag=0){if(flag)return x;T[++cnt]=T[x];return cnt;}
    inline void Mark(int x,int len,int v){T[x].val=v;T[x].sum=len*num[v];}
    inline void pushdown(int x,int lt,int rt)
    {
        int mid=lt+rt>>1;
        Mark(T[x].l=newnode(T[x].l),mid-lt+1,T[x].val);Mark(T[x].r=newnode(T[x].r),rt-mid,T[x].val);T[x].val=0;
    }
    
    int Build(int l,int r)
    {
        int x=++cnt;
        if(l!=r) T[x].l=Build(l,l+r>>1),T[x].r=Build((l+r>>1)+1,r);
        return x; 
    }
    
    int Query(int x,int l,int r,int lt,int rt)
    {
        if(l==lt&&r==rt) return T[x].sum;int mid=lt+rt>>1;
        if(T[x].val) pushdown(x,lt,rt);
        if(r<=mid) return Query(T[x].l,l,r,lt,mid);
        else if(l>mid) return Query(T[x].r,l,r,mid+1,rt);
        else return Query(T[x].l,l,mid,lt,mid)+Query(T[x].r,mid+1,r,mid+1,rt);
    }
    
    int Query(int x,int k,int lt,int rt)
    {
        if(lt==rt) return T[x].val;int mid=lt+rt>>1;
        if(T[x].val) pushdown(x,lt,rt);
        if(k>mid) return Query(T[x].r,k,mid+1,rt);
        else return Query(T[x].l,k,lt,mid);
    }
    
    void Modify(int x,int l,int r,int lt,int rt,int v)
    {
        if(l==lt&&r==rt) {Mark(x,rt-lt+1,v);return;}    
        int mid=lt+rt>>1,flag=T[x].val;
        if(T[x].val) pushdown(x,lt,rt);
        if(r<=mid) Modify(T[x].l=newnode(T[x].l,flag),l,r,lt,mid,v);
        else if(l>mid) Modify(T[x].r=newnode(T[x].r,flag),l,r,mid+1,rt,v);
        else Modify(T[x].l=newnode(T[x].l,flag),l,mid,lt,mid,v),
             Modify(T[x].r=newnode(T[x].r,flag),mid+1,r,mid+1,rt,v);
        T[x].sum=T[T[x].l].sum+T[T[x].r].sum;
    }
    int last=0;
    int main()
    {
        n=read();m=read();ty=read();rt[0]=Build(1,n);
        for(int i=1;i<=m;++i)
        {
            int op=read();rt[i]=newnode(rt[i-1]);
            if(op==1) {int l=(read()+last*ty)%n+1,r=(read()+last*ty)%n+1;printf("%d
    ",last=Query(rt[i],min(l,r),max(l,r),1,n));}
            if(op==2) {int x=(read()+last*ty)%n+1,y=Query(rt[i],x,1,n);if(y!=0) Modify(rt[i],x,x,1,n,Query(rt[y-1],x,1,n));}
            if(op==3) {int l=(read()+last*ty)%n+1,r=(read()+last*ty)%n+1;num[i]=read();Modify(rt[i],min(l,r),max(l,r),1,n,i);}    
        }
        return 0;
    }
  • 相关阅读:
    点子
    evil idea
    ubuntu 10.04.3 modify source.list
    点子
    ubuntu常用软件安装
    架构技术介绍网站
    点子
    点子
    【转发】上海地区工作,全国找网络底层技术开发大牛,旅游方面的创业项目。
    文本相似度计算余弦定理和广义Jaccard系数
  • 原文地址:https://www.cnblogs.com/FallDream/p/uoj218.html
Copyright © 2020-2023  润新知