- 答疑
不同的数
- 2025-10-4 21:48:55 @
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int N = 1e5 + 5;
int n, m;
int a[N];
ll tr[N * 4];
// 向上合并信息,父节点的mask是两个子节点的mask的并集
void psh(int u) {
tr[u] = tr[u << 1] | tr[u << 1 | 1];
}
// 构建线段树
void bld(int u, int l, int r) {
if (l == r) {
tr[u] = 1LL << (a[l] - 1);
return;
}
int mid = (l + r) >> 1;
bld(u << 1, l, mid);
bld(u << 1 | 1, mid + 1, r);
psh(u);
}
// 单点修改
void upd(int u, int l, int r, int x, int v) {
if (l == r) {
tr[u] = 1LL << (v - 1);
return;
}
int mid = (l + r) >> 1;
if (x <= mid) {
upd(u << 1, l, mid, x, v);
} else {
upd(u << 1 | 1, mid + 1, r, x, v);
}
psh(u);
}
// 区间查询
ll ask(int u, int l, int r, int ql, int qr) {
if (ql <= l && r <= qr) {
return tr[u];
}
int mid = (l + r) >> 1;
ll res = 0;
if (ql <= mid) {
res |= ask(u << 1, l, mid, ql, qr);
}
if (qr > mid) {
res |= ask(u << 1 | 1, mid + 1, r, ql, qr);
}
return res;
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin >> n >> m;
for (int i = 1; i <= n; ++i) {
cin >> a[i];
}
bld(1, 1, n);
while (m--) {
int op;
cin >> op;
if (op == 1) {
int l, r;
cin >> l >> r;
ll res = ask(1, 1, n, l, r);
cout << __builtin_popcountll(res) << "\n";
} else {
int x, y;
cin >> x >> y;
upd(1, 1, n, x, y);
}
}
return 0;
}
0 条评论
目前还没有评论...
YIZHIYANG 一只羊 LV 9
推荐阅读