zoukankan      html  css  js  c++  java
  • UNR #1 火车管理

    很简单

    用一个线段树维护

    1.答案

    2.当前栈顶是什么时候push进来的

    然后用一棵以时间为版本的可持久化线段树维护每个操作之后第一个覆盖到他的操作是哪个

    就可以了

    询问直接在线段树上询问,修改在两棵树上分别修改即可

    调一年

    //wls niubi!
    #include<bits/stdc++.h>
    #define LL long long
    using namespace std;
    inline int read()
    {
        int x = 0,f = 1;char ch = getchar();
        for(;!isdigit(ch);ch = getchar())if(ch == '-')f = -f;
        for(;isdigit(ch);ch = getchar())x = 10 * x + ch - '0';
        return x * f;
    }
    const int maxn = 500010;
    int n,m,ty,rt;
    int tot;
    int dfn,root[maxn],ls[maxn << 7],rs[maxn << 7],val[maxn << 7],tag[maxn << 7],w[maxn];
    inline void pushdown(int x,int l,int r)
    {
        if(l == r || !tag[x])return;
        int t = tag[x],mid = (l + r) >> 1;tag[x] = 0;
        if(!ls[x])ls[x] = ++dfn;
        if(!rs[x])rs[x] = ++dfn;
        tag[ls[x]] = tag[rs[x]] = t;
        val[ls[x]] = w[t] * (mid - l + 1);
        val[rs[x]] = w[t] * (r - mid);
    }
    inline int query(int x,int l,int r,int L,int R)
    {
        if(!x)return 0;
        pushdown(x,l,r);
        if(L <= l && r <= R)return val[x];
        int mid = (l + r) >> 1,ans = 0;
        if(L <= mid)ans += query(ls[x],l,mid,L,R);
        if(R > mid)ans += query(rs[x],mid + 1,r,L,R);
        return ans;/*
        if(R <= mid)return query(ls[x],l,mid,L,R);
        else if(L > mid)return query(rs[x],mid + 1,r,L,R);
        else return query(ls[x],l,mid,L,R) + query(rs[x],mid + 1,r,L,R);*/
    }
    inline int qid_1(int x,int l,int r,int p)
    {
        if(tag[x])return tag[x];
        if(l == r)return tag[x];
        int mid = (l + r) >> 1;
        if(p <= mid)return qid_1(ls[x],l,mid,p);
        else return qid_1(rs[x],mid + 1,r,p);
    }
    inline int qid_2(int x,int l,int r,int p)
    {
        pushdown(x,l,r);
        if(l == r)return tag[x];
        int mid = (l + r) >> 1;
        if(p <= mid)return qid_2(ls[x],l,mid,p);
        else return qid_2(rs[x],mid + 1,r,p);
    }
    inline void modify(int &x,int l,int r,int L,int R,int va)
    {
        if(!x)x = ++dfn;
        pushdown(x,l,r);
        if(L <= l && r <= R)
        {
            tag[x] = va;
            val[x] = (r - l + 1) * w[va];
            return;
        }
        int mid = (l + r) >> 1;
        if(L <= mid)modify(ls[x],l,mid,L,R,va);
        if(R > mid)modify(rs[x],mid + 1,r,L,R,va);
        val[x] = val[ls[x]] + val[rs[x]];
    }
    inline void Cpushdown(int x)
    {
        if(!tag[x])return;
        int v = tag[x],tmp;tag[x] = 0;
        tmp = ls[x],ls[x] = ++dfn;ls[ls[x]] = ls[tmp],rs[ls[x]] = rs[tmp],tag[ls[x]] = tag[tmp],val[ls[x]] = val[tmp];
        tmp = rs[x],rs[x] = ++dfn;ls[rs[x]] = ls[tmp],rs[rs[x]] = rs[tmp],tag[rs[x]] = tag[tmp],val[rs[x]] = val[tmp];
        tag[ls[x]] = tag[rs[x]] = v;
    }
    inline void insert(int &x,int l,int r,int L,int R,int va,int flg)
    {
        if(flg)
        {
            int p = x;
            x = ++dfn;
            ls[x] = ls[p],rs[x] = rs[p],tag[x] = tag[p],val[x] = val[p];
        }
        flg = 1;
        if(l < r && tag[x])Cpushdown(x),flg = 0;
        if(L <= l && r <= R){tag[x] = va;return;}
        int mid = (l + r) >> 1;
        if(L <= mid)insert(ls[x],l,mid,L,R,va,flg);
        if(R > mid)insert(rs[x],mid + 1,r,L,R,va,flg);
    }
    int main()
    {
        n=read();m=read();ty=read();
        int ans=0;
        while(m--)
        {
            int op=read();
            if (op==1)
            {
                int l=(read()+ans*ty)%n+1,r=(read()+ans*ty)%n+1;
                if (l>r) swap(l,r);
                printf("%d
    ",ans=query(rt,1,n,l,r));
            }
            else if (op==2)
            {
                int l=(read()+ans*ty)%n+1,id=qid_2(rt,1,n,l);
                id=qid_1(root[id-1],1,n,l);
                modify(rt,1,n,l,l,id);
                tot++;root[tot]=root[tot-1];
                insert(root[tot],1,n,l,l,id,1);
            }
            else
            {
                int l=(read()+ans*ty)%n+1,r=(read()+ans*ty)%n+1,x=read();
                if (l>r) swap(l,r);
                tot++;w[tot]=x;root[tot]=root[tot-1];
                insert(root[tot],1,n,l,r,tot,1);
                modify(rt,1,n,l,r,tot);
            }
        }
    }
    View Code
  • 相关阅读:
    Win10怎么设置虚拟内存?
    树莓派 —— USB 摄像头简单测试 (拍照 & 视频)
    如何设置树莓派 VNC 的分辨率
    树莓派 VNC Viewer 远程桌面配置教程
    数据库开发——MySQL——数据的增删改查
    数据库开发——MySQL——foreign key
    数据库开发——MySQL——primary key
    一种关闭按钮
    oracle下 启动subversion命令 及 oracle相关服务启动备忘
    table内 获取同一行 其他列的value
  • 原文地址:https://www.cnblogs.com/Kong-Ruo/p/9676129.html
Copyright © 2011-2022 走看看