G:n个数,q次操作,把lr区间的x全部变成y,求操作完的结果
解法:线段树维护lazy标记,lazy标记开100倍,表示该节点指向的值,不用加value数组,最后的结果就是直接用叶子节点上的lazy标记修改值,lazy标记pushdown的时候直接对下一层的节点进行修改,时间复杂度O(n*logn*100)
#include<bits/stdc++.h> #define fi first #define se second #define mp make_pair #define pb push_back #define pi acos(-1.0) #define ll long long #define mod 1000000007 #define C 0.5772156649 #define ls l,m,rt<<1 #define rs m+1,r,rt<<1|1 #define pil pair<int,ll> #define pii pair<int,int> #define ull unsigned long long #define base 1000000000000000000 #define fio ios::sync_with_stdio(false);cin.tie(0) using namespace std; const double g=10.0,eps=1e-12; const int N=200000+10,maxn=400000+10,inf=0x3f3f3f3f; int lazy[N<<2][101]; int a[N]; bool ok[N<<2]; void pushdown(int rt) { for(int i=1;i<=100;i++) { lazy[rt<<1][i]=lazy[rt][lazy[rt<<1][i]]; lazy[rt<<1|1][i]=lazy[rt][lazy[rt<<1|1][i]]; } for(int i=1;i<=100;i++)lazy[rt][i]=i; ok[rt<<1]=ok[rt<<1|1]=1; ok[rt]=0; } void build(int l,int r,int rt) { for(int i=1;i<=100;i++)lazy[rt][i]=i; if(l==r)return ; int m=(l+r)>>1; build(ls); build(rs); } void update(int L,int R,int x,int y,int l,int r,int rt) { if(L<=l&&r<=R) { for(int i=1;i<=100;i++) if(lazy[rt][i]==x) lazy[rt][i]=y; ok[rt]=1; return ; } if(ok[rt])pushdown(rt); int m=(l+r)>>1; if(L<=m)update(L,R,x,y,ls); if(m<R)update(L,R,x,y,rs); } void dfs(int l,int r,int rt) { if(l==r) { a[l]=lazy[rt][a[l]]; return ; } if(ok[rt])pushdown(rt); int m=(l+r)>>1; dfs(ls);dfs(rs); } int main() { int n; scanf("%d",&n); for(int i=1;i<=n;i++)scanf("%d",&a[i]); build(1,n,1); int q; scanf("%d",&q); while(q--) { int l,r,x,y; scanf("%d%d%d%d",&l,&r,&x,&y); update(l,r,x,y,1,n,1); } dfs(1,n,1); for(int i=1;i<=n;i++)printf("%d ",a[i]); puts(""); return 0; } /******************** 5 1 2 3 4 5 2 1 5 5 1 1 5 1 5 ********************/