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

 

转载于:https://www.cnblogs.com/Kong-Ruo/p/9676129.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值