• CF911G Mass Change Queries- 动态开点线段树


    给出一个数列,有q个操作,每种操作是把区间[l,r]中等于x的数改成y.输出q步操作完的数列.
    https://www.luogu.com.cn/problem/CF911G
    输入 #1 复制
    5
    1 2 3 4 5
    3
    3 5 3 5
    1 5 5 1
    1 5 1 5
    输出 #1 复制
    5 2 5 4 5


    题解

    • 线段树动态开点板题(线段树合并)

    代码

    #include <iostream>
    #include <cstdio>
    using namespace std;
    int n,cnt,ans[200003],root[200003];
    struct fdfdfd{int l,r;}a[10000003];
    void add(int &x,int left,int right,int d)
    {
    	if(left>d||right<d) return;
    	if(!x) x=++cnt;
    	if(left==right) return;
    	int mid=(left+right)>>1;
    	add(a[x].l,left,mid,d); add(a[x].r,mid+1,right,d);
    }
    int merge(int x,int y)
    {
    	if(!x||!y) return x|y;
    	a[x].l=merge(a[x].l,a[y].l);
    	a[x].r=merge(a[x].r,a[y].r);
    	return x;
    }
    void modify(int &x,int &y,int left,int right,int dx,int dy)
    {
    	if(!x||left>dy||right<dx) return;
    	if(left>=dx&&right<=dy) {y=merge(x,y),x=0; return;}
    	if(!y) y=++cnt;
    	int mid=(left+right)>>1;
    	modify(a[x].l,a[y].l,left,mid,dx,dy);
    	modify(a[x].r,a[y].r,mid+1,right,dx,dy);
    }
    void change(int x,int left,int right,int col)
    {
    	if(!x) return;
    	if(left==right) {ans[left]=col; return;}
    	int mid=(left+right)>>1;
    	change(a[x].l,left,mid,col); change(a[x].r,mid+1,right,col);
    }
    int main()
    {
    	scanf("%d",&n);
    	for(int i=1,x;i<=n;++i) scanf("%d",&x),add(root[x],1,n,i);
    	int m; scanf("%d",&m);
    	for(int i=1,x,y,l,r;i<=m;++i)
    	{
    		scanf("%d%d%d%d",&l,&r,&x,&y);
    		if(x!=y) modify(root[x],root[y],1,n,l,r);
    	}
    	for(int i=1;i<=100;++i) change(root[i],1,n,i);
    	for(int i=1;i<=n;++i) cout<<ans[i]<<' ';
    	return 0;
    }
    
  • 相关阅读:
    JS数组及操作方法,堆和栈的概念
    JS变量作用域,浏览器预解析
    JS函数的基本概念
    JS循环语句
    JS程序三大结构及语法语句
    src与href
    JS概念及基本语法
    图片整合技术
    hdu6395 Sequence(分段矩阵快速幂)
    hdu6396 Swordsman(贪心)
  • 原文地址:https://www.cnblogs.com/wuwendongxi/p/14184472.html
Copyright © 2020-2023  润新知