CF848C Goodbye Souvenir
https://www.luogu.com.cn/problem/CF848C
问题可以转化成
求
∑
i
−
p
r
e
i
[
p
r
e
i
>
=
L
,
i
<
=
R
]
\sum i - pre_{i}[pre_i>=L,i<=R]
∑i−prei[prei>=L,i<=R]
再加上修改有一维是时间
t
t
t
就是一个三维偏序
code:
#include<bits/stdc++.h>
#define lowbit(x) (x & -x)
#define N 1000005
#define ll long long
using namespace std;
set<int> mp[N];
int gpre(int x, int y) {
set<int>::iterator it = mp[x].lower_bound(y); it --;
return *it;
}
int gnxt(int x, int y) {
return *(mp[x].upper_bound(y));
}
int n, pre[N], nxt[N], col[N], m, sz;
ll tree[N], ANS[N];
void update(int x, int y) { if(x)
for(; x <= n; x += lowbit(x)) tree[x] += y;
}
ll query(int x) {
ll ret = 0;
for(; x; x -= lowbit(x)) ret += tree[x];
return ret;
}
struct A {
int opt, x, y, val, id;
} a[N];
void change(int x, int y) {
a[++ sz] = A{0, x, pre[x], -(x - pre[x]), 0};
pre[x] = y;
a[++ sz] = A{0, x, pre[x], x - pre[x], 0};
}
int cmp(A x, A y) {
if(x.opt != y.opt) return x.opt < y.opt;
if(x.opt) return x.y < y.y;
return x.x < y.x;
}
void cdq(int l, int r) {
if(l == r) return;
int mid = (l + r) >> 1;
cdq(l, mid), cdq(mid + 1, r);
sort(a + mid + 1, a + r + 1, cmp);
int pos = l - 1;
for(int i = mid + 1; i <= r; i ++) if(a[i].opt == 1){
while(pos < mid && (a[pos + 1].opt == 1 || a[pos + 1].x <= a[i].y)) {
pos ++;
if(!a[pos].opt) update(a[pos].y, a[pos].val);
}
ANS[a[i].id] += query(n) - query(a[i].x - 1);
}
for(int i = l; i <= pos; i ++) if(!a[i].opt) update(a[i].y, - a[i].val);
sort(a + l, a + r + 1, cmp);
}
int main() {
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; i ++) mp[i].insert(0), mp[i].insert(n + 1);
for(int i = 1; i <= n; i ++) {
scanf("%d", &col[i]);
mp[col[i]].insert(i);
}
for(int i = 1; i <= n; i ++)
pre[i] = gpre(col[i], i), nxt[i] = gnxt(col[i], i), a[++ sz] = A{0, i, pre[i], i - pre[i], 0};
int ha = 0;
for(int i = 1; i <= m; i ++) {
int opt, x, y;
scanf("%d%d%d", &opt, &x, &y);
if(opt == 1) {
int pree = gpre(y, x), nxtt = gnxt(y, x);
mp[col[x]].erase(x), mp[y].insert(x);
col[x] = y;
if(nxt[x] != n + 1) change(nxt[x], pre[x]);
if(pre[x]) nxt[pre[x]] = nxt[x];
if(nxtt != n + 1) change(nxtt, x);
if(pree) nxt[pree] = x;
change(x, pree);
nxt[x] = nxtt;
} else a[++ sz] = A{1, x, y, 0, ++ ha};
}
cdq(1, sz);
for(int i = 1; i <= ha; i ++) printf("%lld\n", ANS[i]);
return 0;
}