zoukankan      html  css  js  c++  java
  • 【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;
    }
  • 相关阅读:
    .net core 3.1 使用Redis缓存
    JavaSE 高级 第11节 缓冲输入输出字节流
    JavaSE 高级 第10节 字节数组输出流ByteArrayOutputStream
    JavaSE 高级 第09节 字节数组输入流ByteArrayInputStream
    JavaSE 高级 第08节 文件输出流FileOutputStream
    JavaSE 高级 第07节 文件输入流FileInputStream
    JavaSE 高级 第06节 初识I、O流
    JavaSE 高级 第05节 日期类与格式化
    JavaSE 高级 第04节 StringBuffer类
    JavaSE 高级 第03节 Math类与猜数字游戏
  • 原文地址:https://www.cnblogs.com/FallDream/p/uoj218.html
Copyright © 2011-2022 走看看