观察,数组的值域不是很大,只有100,因此可以根据下标动态开点,修改,就是将权值为x的子树加到权值为y的树上去,还是比较好想
#include <bits/stdc++.h>
#define inf 0x7fffffff
#define ll long long
//#define int long long
//#define double long double
#define re register int
#define void inline void
#define eps 1e-8
//#define mod 1e9+7
#define ls(p) p<<1
#define rs(p) p<<1|1
#define pi acos(-1.0)
#define pb push_back
#define P pair < int , int >
#define mk make_pair
using namespace std;
const int mod=1e9+7;
const int M=1e9;
const int N=2e7+5;//?????????? 4e8
int lc[N],rc[N];
int rt[N],ans[N],tot;
int n,m;
void bulid(int &p,int l,int r,int pos)
{
if(!p) p=++tot;
if(l==r) return;
int mid=(l+r)>>1;
if(pos<=mid) bulid(lc[p],l,mid,pos);
else bulid(rc[p],mid+1,r,pos);
}
int merge(int p1,int p2)
{
if(!p1||!p2) return p1+p2;
lc[p1]=merge(lc[p1],lc[p2]);
rc[p1]=merge(rc[p1],rc[p2]);
return p1;
}
void update(int &p1,int &p2,int L,int R,int l,int r)
{
if(!p1) return;
if(L<=l&&r<=R)
{
p2=merge(p1,p2);
p1=0;
return;
}
int mid=(l+r)>>1;
if(!p2) p2=++tot;
if(L<=mid) update(lc[p1],lc[p2],L,R,l,mid);
if(mid<R) update(rc[p1],rc[p2],L,R,mid+1,r);
}
void ask(int p,int l,int r,int val)
{
if(!p) return;
if(l==r)
{
// cout<<l<<" ";
ans[l]=val;
return;
}
int mid=(l+r)>>1;
ask(lc[p],l,mid,val);
ask(rc[p],mid+1,r,val);
}
void solve()
{
cin>>n;
for(re i=1;i<=n;i++)
{
int x;
scanf("%d",&x);
bulid(rt[x],1,n,i);
}
cin>>m;
while(m--)
{
int l,r,x,y;
scanf("%d%d%d%d",&l,&r,&x,&y);
if(x==y) continue;
update(rt[x],rt[y],l,r,1,n);
}
for(re i=1;i<=100;i++) ask(rt[i],1,n,i);
for(re i=1;i<=n;i++) printf("%d ",ans[i]);
}
signed main()
{
// freopen("P1505_1.txt", "r", stdin);
// freopen("Aout.txt", "w", stdout);
int T=1;
// cin>>T;
for(int index=1;index<=T;index++)
{
// printf("Case #%lld: ",index);
solve();
// puts("");
}
return 0;
}
/*
5
2 1 2 2 2
1
1 5 2 1
*/