LibreOJ #6284
题目链接:#6284. 数列分块入门 8
题目大意
给出一个长为 \(n\) 的数列,以及 \(n\) 个操作,操作涉及区间询问等于一个数 \(c\) 的元素,并将这个区间的所有元素改为 \(c\)。
solution
又是我们喜爱的分块
我们怎么做呢, 我们讲区间内全部相同的打一个标记, 记录这个区间的值,然后计算的时候加上这个区间的长度就好了,然后不相同的我们直接暴力查找就好了
我们在散块处理的时候记得把标记下放,不然会哭的
Code:
/**
* Author: Alieme
* Data: 2020.9.8
* Problem: LibreOJ #6284
* Time: O()
*/
#include <cstdio>
#include <iostream>
#include <string>
#include <cstring>
#include <cmath>
#include <algorithm>
#define int long long
#define rr register
#define inf 1e9
#define MAXN 200010
using namespace std;
inline int read() {
int s = 0, f = 0;
char ch = getchar();
while (!isdigit(ch)) f |= ch == '-', ch = getchar();
while (isdigit(ch)) s = s * 10 + (ch ^ 48), ch = getchar();
return f ? -s : s;
}
void print(int x) {
if (x < 0) putchar('-'), x = -x;
if (x > 9) print(x / 10);
putchar(x % 10 + 48);
}
int n, len;
int a[MAXN], id[MAXN], f[MAXN];
inline void reset(int x) {
if (f[x] == -1) return ;
for (rr int i = (x - 1) * len + 1; i <= min(x * len, n); i++) a[i] = f[x];
f[x] = -1;
}
inline void change(int l, int r, int x) {
int start = id[l], end = id[r];
if (start == end) {
reset(start);
for (rr int i = l; i <= r; i++) a[i] = x;
return ;
}
reset(start), reset(end);
for (rr int i = l; id[i] == start; i++) a[i] = x;
for (rr int i = start + 1; i < end; i++) f[i] = x;
for (rr int i = r; id[i] == end; i--) a[i] = x;
}
inline int query(int l, int r, int x) {
int start = id[l], end = id[r], ans = 0;
if (start == end) {
reset(start);
for (rr int i = l; i <= r; i++) if (a[i] == x) ans++;
return ans;
}
reset(start), reset(end);
for (rr int i = l; id[i] == start; i++) if (a[i] == x) ans++;
for (rr int i = start + 1; i < end; i++)
if (f[i] == x) ans += len;
else if (f[i] == -1) for (rr int j = (i - 1) * len + 1; j <= i * len; j++) if (a[j] == x) ans++;
for (rr int i = r; id[i] == end; i--) if (a[i] == x) ans++;
return ans;
}
signed main() {
// freopen("a1.in", "r", stdin);
// freopen("a.out", "w", stdout);
n = read();
len = sqrt(n);
for (rr int i = 1; i <= n; i++) a[i] = read(), id[i] = (i - 1) / len + 1, f[id[i]] = -1;
for (rr int i = 1; i <= n; i++) {
int l = read(), r = read(), c = read();
cout << query(l, r, c) << "\n";
change(l, r, c);
}
}
时间会刺破青春表面的彩饰,会在美人的额上掘深沟浅槽;会吃掉稀世之珍!天生丽质,什么都逃不过他那横扫的镰刀。
博主写的那么好,就不打赏一下么(打赏在右边)