社区讨论
关于分块
学术版参与者 4已保存回复 7
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 7 条
- 当前快照
- 1 份
- 快照标识符
- @mhk7d3sk
- 此快照首次捕获于
- 2025/11/04 14:43 4 个月前
- 此快照最后确认于
- 2025/11/04 14:43 4 个月前
分块入门 8 的想法
题意: 次操作,每次求出区间中等于 的数字,再将整个区间覆盖为 。
想法:记录当前块中被整体覆盖的最后一个值,查询时用二分求出大于 和大于等于 的数字个数相减就是等于 的个数。
想知道这个做法有没有正确性,会不会 TLE。
代码如下
CPP#include <bits/stdc++.h>
#define int long long
#define pb push_back
using namespace std;
const int maxn = 1e5 + 10, maxk = 4e2 + 10, inf = 1e10;
int n, m, len, a[maxn], pos[maxn];
struct node {
int l, r, c;
}t[maxk];
vector<int> v[maxk];
void blk_init() {
len = sqrt(n), m = (n % len ? len + 1 : len);
for (int i = 1; i <= m; ++i) t[i] = {(i - 1) * len, i * len, inf};
t[m].r = n;
for (int i = 1; i <= m; ++i) {
for (int j = t[i].l; i <= t[i].r; ++i) pos[j] = i, v[i].pb(a[j]);
sort(v[i].begin(), v[i].end());
}
}
void rebd(int u) {
v[u].clear();
for (int i = t[u].l; i <= t[u].r; ++i) v[u].pb(a[i]);
}
void modify(int l, int r, int c) {
int pl = pos[l], pr = pos[r];
if (pl == pr) {
for (int i = l; i <= r; ++i) a[i] = c;
rebd(pl);
return;
}
for (int i = l; i <= t[pl].r; ++i) a[i] = c;
rebd(pl);
for (int i = t[pr].l; i <= r; ++i) a[i] = c;
rebd(pr);
for (int i = pl + 1; i <= pr - 1; ++i) t[i].c = c;
}
int query(int l, int r, int c) {
int pl = pos[l], pr = pos[r], res = 0;
if (pl == pr) {
if (t[pl].c == c) return t[pl].r - t[pl].l + 1;
for (int i = l; i <= r; ++i) res += (a[i] == c);
return res;
}
if (t[pl].c == c) res += t[pl].r - l + 1;
else for (int i = l; i <= t[pl].r; ++i) res += (a[i] == c);
if (t[pr].c == c) res += r - t[pr].l + 1;
else for (int i = t[pr].l; i <= r; ++i) res += (a[i] == c);
for (int i = pl + 1, p1, p2; i <= pr - 1; ++i) {
if (t[i].c == c) {
res += t[i].r - t[i].l + 1;
continue;
}
p1 = upper_bound(v[i].begin(), v[i].end(), c) - v[i].begin();
p2 = lower_bound(v[i].begin(), v[i].end(), c) - v[i].begin();
if (v[i][p2] != c) continue;
res += p1 - p2;
}
}
signed main() {
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
cin >> n;
for (int i = 1; i <= n; ++i) cin >> a[i];
blk_init();
for (int i = 1, l, r, c; i <= n; ++i) {
cin >> l >> r >> c;
cout << query(l, r, c) << '\n';
modify(l, r, c);
}
return 0;
}
回复
共 7 条回复,欢迎继续交流。
正在加载回复...