Mass Change Queries CodeForces - 911G (线段树合并)

链接

大意: 给定序列, 每次操作将区间[l,r]中的x全改为y, 最后输出序列

权值范围比较小, 对每个权值开一颗线段树, 每次将x合并到y上即可

#include <iostream>
#include <algorithm>
#include <cstdio>
#define REP(i,a,n) for(int i=a;i<=n;++i)
#define mid (l+r>>1)
#define lc (o<<1)
#define rc (lc|1)

using namespace std;
typedef long long ll;

const int N = 2e5+10;
int a[N], n, m, t;
int rt[110], tot, ql, qr, now;
struct _ {int l,r;}v[N<<5];

void ins(int &o, int l, int r, int pos) {
	if (!o) o=++tot;
	if (l==r) return;
	if (mid>=pos) ins(v[o].l,l,mid,pos);
	else ins(v[o].r,mid+1,r,pos);
}

int merge(int x, int y) {
	if (!x||!y) return x^y;
	v[x].l = merge(v[x].l,v[y].l);
	v[x].r = merge(v[x].r,v[y].r);
	return x;
}

void update(int &x, int &y, int l, int r) {
	if (!x) return;
	if (ql<=l&&r<=qr) return y=merge(x,y),void(x=0);
	if (!y) y=++tot;
	if (mid>=ql) update(v[x].l,v[y].l,l,mid);
	if (mid<qr) update(v[x].r,v[y].r,mid+1,r);
}

void dfs(int o, int l, int r) {
	if (!o) return;
	if (l==r) return void(a[l]=now);
	dfs(v[o].l,l,mid),dfs(v[o].r,mid+1,r);
}

int main() {
	scanf("%d", &n);
	REP(i,1,n) {
		int t;
		scanf("%d", &t);
		ins(rt[t],1,n,i);
	}
	scanf("%d", &m);
	while (m--) {
		int x, y;
		scanf("%d%d%d%d", &ql, &qr, &x, &y);
		if (x!=y) update(rt[x],rt[y],1,n);
	}
	REP(i,1,100) now=i,dfs(rt[i],1,n);
	REP(i,1,n) printf("%d ",a[i]);
	puts("");
}

原文地址:https://www.cnblogs.com/uid001/p/10409946.html

时间: 2024-07-30 14:11:16

Mass Change Queries CodeForces - 911G (线段树合并)的相关文章

Alyona and a tree CodeForces - 739B (线段树合并)

大意: 给定有根树, 每个点$x$有权值$a_x$, 对于每个点$x$, 求出$x$子树内所有点$y$, 需要满足$dist(x,y)<=a_y$. 刚开始想错了, 直接打线段树合并了.....因为范围是$long \space long$常数极大, 空间很可能会被卡, 不过竟然过了. 实际上本题每个点对树链上的贡献是单调的, 直接二分就行了 放一下线段树合并代码 #include <iostream> #include <algorithm> #include <cs

CodeForces 600E Lomsat gelral(线段树合并)

题目链接:http://codeforces.com/problemset/problem/600/E You are given a rooted tree with root in vertex 1. Each vertex is coloured in some colour. Let's call colour c dominating in the subtree of vertex v if there are no other colours that appear in the

Codeforces Gym 101194G Pandaria (2016 ACM-ICPC EC-Final G题, 并查集 + 线段树合并)

题目链接  2016 ACM-ICPC EC-Final Problem G 题意  给定一个无向图.每个点有一种颜色. 现在给定$q$个询问,每次询问$x$和$w$,求所有能通过边权值不超过w的边走到$x$的点的集合中,哪一种颜色的点出现的次数最多. 次数相同时输出编号最小的那个颜色.强制在线. 求哪种颜色可以用线段树合并搞定. 关键是这个强制在线. 当每次询问的时候,我们先要求出最小生成树在哪个时刻恰好把边权值不超过$w$的边都用并查集合并了. 在做最小生成树的时候每合并两个节点,另外开一个

Educational Codeforces Round 47 (Rated for Div. 2)F. Dominant Indices 线段树合并

题意:有一棵树,对于每个点求子树中离他深度最多的深度是多少, 题解:线段树合并快如闪电,每个节点开一个权值线段树,递归时合并即可,然后维护区间最多的是哪个权值,到x的深度就是到根的深度减去x到根的深度复杂度O(nlogn) //#pragma comment(linker, "/stack:200000000") //#pragma GCC optimize("Ofast,no-stack-protector") //#pragma GCC target("

Codeforces ECR47F Dominant Indices(线段树合并)

一个比较显然的做法:对每棵子树用线段树维护其中的深度,线段树合并即可. 本来想用这个题学一下dsu on tree,结果还是弃疗了. #include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> #include<cstring> #include<algorithm> using namespace std; int read() { int x=0,f=

codeforces 600E . Lomsat gelral (线段树合并)

You are given a rooted tree with root in vertex 1. Each vertex is coloured in some colour. Let's call colour c dominating in the subtree of vertex v if there are no other colours that appear in the subtree of vertex v more times than colour c. So it'

Codeforces.1051G.Distinctification(线段树合并 并查集)

题目链接 \(Description\) 给定\(n\)个数对\(A_i,B_i\).你可以进行任意次以下两种操作: 选择一个位置\(i\),令\(A_i=A_i+1\),花费\(B_i\).必须存在一个位置\(j\),满足\(A_i=A_j,\ i\neq j\),才可以进行. 选择一个位置\(i\),令\(A_i=A_i-1\),花费\(-B_i\).必须存在一个位置\(j\),满足\(A_i=A_j+1\),才可以进行. 你需要对于所有\(i\in[1,n]\),求使得\(A_1,A_2,

BZOJ2243 [SDOI2011]染色(树链剖分+线段树合并)

题目链接 BZOJ2243 树链剖分+线段树合并 线段树合并的一些细节需要注意一下 #include <bits/stdc++.h> using namespace std; #define rep(i, a, b) for (int i(a); i <= (b); ++i) #define dec(i, a, b) for (int i(a); i >= (b); --i) typedef long long LL; const int N = 100010; int n, m,

[POI2011]ROT-Tree Rotations 线段树合并|主席树 / 逆序对

题目[POI2011]ROT-Tree Rotations [Description] 现在有一棵二叉树,所有非叶子节点都有两个孩子.在每个叶子节点上有一个权值(有\(n\)个叶子节点,满足这些权值为\(1..n\)的一个排列).可以任意交换每个非叶子节点的左右孩子. 要求进行一系列交换,使得最终所有叶子节点的权值按照中序遍历写出来,逆序对个数最少. [Input Format] 第一行一个整数\(n\). 下面每行,一个数\(x\). 如果\(x =0\),表示这个节点非叶子节点,递归地向下读