传送门 : HDU 5997
最初想过用vector存储, 但是没敢写….
区间合并 + 成段更新
这题和普通线段树区间更新的区别就是待更新的区间不确定, 所以只要把要更新区间表示出来, 就行了
x -> y找到x代表的vector存储的多个成段区间, 一个个更新,
这些段加到y的段里, 然后清楚x的段
今天水过结果920MS,目前垫底。。。。打不动
#include
#include
#include
#include
#include
using namespace std;
#define mid ((l + r) >> 1)
#define ls rt << 1, l, mid
#define rs rt << 1 | 1, mid + 1, r
typedef long long LL;
const int maxn = 1000000 + 5;
int n, q;
struct Node{
int lv, rv, ans, la;
}node[maxn << 2];
int co[maxn];
struct Seg{//段
int l, r;
};
vector s[maxn];
void pushUp(Node &res, Node p, Node q) {//合并
res.lv = p.lv;
res.rv = q.rv;
res.ans = p.ans + q.ans;
if (p.rv == q.lv) --res.ans;
}
void build(int rt, int l, int r) {
node[rt].la = 0;
if (l == r) {
//scanf("%d", &node[rt].lv);
node[rt].ans = 1;
node[rt].rv = node[rt].lv = co[l];
return;
}
build(ls);
build(rs);
pushUp(node[rt], node[rt << 1], node[rt << 1 | 1]);
}
void down(int f, int s) {
node[s].la = node[f].la;
node[s].lv = node[f].lv;
node[s].rv = node[f].rv;
node[s].ans = 1;
}
void pushDown(int rt) {
if (node[rt].la) {
down(rt, rt << 1);
down(rt, rt << 1 | 1);
node[rt].la = 0;
}
}
void update(int rt, int l, int r, int L, int R, int b) {
//printf("%d %d %d %d\n", l, r, L, R);
if (L <= l && R >= r) {
node[rt].lv = node[rt].rv = b;
node[rt].la = b;
return;
}
pushDown(rt);
if(L <= mid) update(ls, L, R, b);
if(R > mid ) update(rs, L, R, b);
pushUp(node[rt], node[rt << 1], node[rt << 1 | 1]);
}
Node query(int rt, int l, int r, int L, int R) {
if (L == l && R == r) {
return node[rt];
}
//pushDown(rt);
Node p, q, res;
if (L > mid) {
return query(rs, L, R);
}
if (R <= mid) {
return query(ls, L, R);
}
p = query(ls, L, mid);
q = query(rs, mid + 1, R);
pushUp(res, p, q);
return res;
}
int main() {
//freopen("in.txt", "r", stdin);
cin.tie(0);
cin.sync_with_stdio(false);
int T, op, a, b;
scanf("%d", &T);
while (T--) {
scanf("%d%d", &n, &q);
for (int i = 0; i < 1000000; ++i) s[i].clear();
int tmp = -1;
Seg tt;
for (int i = 1; i <= n; ++i) {//预处理
scanf("%d", &co[i]);
if (tmp == -1) {
tt.l = i;
tmp = co[i];
}
if (tmp != co[i]) {
tt.r = i - 1;
s[tmp].push_back(tt);
tt.l = i;
tmp = co[i];
}
}
tt.r = n;
s[tmp].push_back(tt);
build(1, 1, n);
while (q--) {
scanf("%d%d%d", &op, &a, &b);
if (op == 1) {
if (a == b) continue;
for (int i = 0; i < s[a].size(); ++i) {//update
update(1, 1, n, s[a][i].l, s[a][i].r, b);
s[b].push_back(s[a][i]);
}
s[a].clear();
}
else {
Node tmp = query(1, 1, n, a, b);
printf("%d\n", tmp.ans);
}
}
}
return 0;
}