G. Mass Change Queries

G. Mass Change Queries

分析

我们考虑,如果我们建100颗线段树,那么如何完成将x对应的[l,r]对应的位置,与y对应的[l,r]对应的部分合并?

线段树合并。结束了。

记得特判一下x==y的情况。

AC_code

#include<bits/stdc++.h>
#define ios ios::sync_with_stdio(false); cin.tie(0), cout.tie(0)
using namespace std;

const int N = 1e7 + 10,inf = 0x3f3f3f3f;

int n,m,idx;
int lson[N],rson[N];

int root[120],ans[N];

int merge(int u,int v)
{
    if(!u||!v) return u | v;
    lson[u] = merge(lson[u],lson[v]);
    rson[u] = merge(rson[u],rson[v]);
    return u;
}

void init(int &u,int l,int r,int x)
{
    if(l>x||r<x) return ;
    if(!u) u = ++idx;
    if(l==r) return ;
    int mid = l + r >> 1;
    init(lson[u],l,mid,x);init(rson[u],mid+1,r,x);
}

void modify(int &u,int &v,int l,int r,int L,int R)
{
    if(!u) return ;
    if(l>R||r<L) return ;
    if(L<=l&&r<=R)
    {
        v = merge(u,v);u = 0;
        return ;
    }
    if(!v) v = ++idx;
    int mid = l + r >> 1;
    modify(lson[u],lson[v],l,mid,L,R);
    modify(rson[u],rson[v],mid+1,r,L,R);
}

void print(int u,int l,int r,int x)
{
    if(!u) return ;
    if(l==r) 
    {
        ans[l] = x;
        return ;
    }
    int mid = l + r >> 1;
    print(lson[u],l,mid,x);print(rson[u],mid+1,r,x);
}

int main()
{
    ios;
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        int x;cin>>x;
        init(root[x],1,n,i);
    }
    cin>>m;
    while(m--)
    {
        int l,r;cin>>l>>r;
        int x,y;cin>>x>>y;
        if(x==y) continue;
        modify(root[x],root[y],1,n,l,r);
    }

    for(int i=1;i<=100;i++)
        print(root[i],1,n,i);
    for(int i=1;i<=n;i++) cout<<ans[i]<<" ";
    return 0;
}
posted @ 2022-10-28 21:21  艾特玖  阅读(22)  评论(0)    收藏  举报