思路是并查集+线段树,感觉好像想复杂了,一直TLE 2个点,想问问是复杂度假了还是被卡常了。
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#include <bits/stdc++.h>
using namespace std;
namespace FastIO {
const int SZ = 1 << 18; char *p1, *p2, buf[SZ];
#define getchar() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, SZ, stdin), p1 == p2) ? EOF : *p1++)
inline void skip() {for (char ch = getchar(); ch == ' ' || ch == '\n' || ch == '\t'; ch = getchar());}
int t; char ch;
template <typename T> inline void read(T& x) {x = 0, t = 1, ch = getchar(); for (; ch < '0' || ch > '9'; ch = getchar()) if (ch == '-') t = -1; for (; '0' <= ch && ch <= '9'; ch = getchar()) x = (x << 1) + (x << 3) + (ch ^ 48); x *= t;}
inline void read(char& x) {skip(), x = getchar();}
template <typename T, typename... Args> inline void read(T& t, Args&... args) {read(t); read(args...);}
template <typename It> inline void read(const It& begin, const It& end) {for (It it = begin; it != end; it++) read(*it);}
#ifndef DISABLE_FAST_WRITE
char obuf[SZ], *p3 = obuf;
#define putchar(a) ((p3 - obuf < SZ) ? (*p3++ = a) : (fwrite(obuf, p3 - obuf, 1, stdout), p3 = obuf, *p3++ = a))
inline void flush() {fwrite(obuf, p3 - obuf, 1, stdout);}
#endif //DISABLE_FAST_WRITE
template <typename T> inline void write(T x) {if (x < 0) putchar('-'), x = -x; static int st[40]; int top = 0; do {st[top++] = x % 10, x /= 10;} while (x); while (top) putchar(st[--top] ^ 48);}
inline void write(const char c) {putchar(c);}
inline void write(const std::string& s) {for (char c : s) putchar(c);}
template <typename T> inline void write(const char c, const T x) {write(x), putchar(c);}
template <typename T, typename... Args> inline void write(T t, const char c, Args... args) {write(c, t); write(c, args...);}
template <typename T> inline void writeln(const T x) {write(x), putchar('\n');}
template <typename T> inline void writesp(const T x) {write(x), putchar(' ');}
template <typename It> inline void write(const char c, const It& begin, const It& end) {for (It it = begin; it != end; it++) write(*it), putchar(c);}
} using namespace FastIO;
const int N = 5e5 + 5;
int n, q, opt, x, c, cnt[N];
struct UnionFind {
int fa[N];
UnionFind() {iota(fa, fa + N + 1, 0);}
int find(int x) {return x == fa[x] ? x : find(fa[x]);}
} L, R;
#define ls (rt << 1)
#define rs (rt << 1 | 1)
const int null = -114514;
int val[N << 2], cover[N << 2];
void pushdown(int rt) {
if (cover[rt] == null) return;
val[ls] = val[rs] = cover[rt], cover[ls] = cover[rs] = cover[rt];
cover[rt] = null;
}
void build(int l, int r, int rt) {
cover[rt] = null;
if (l == r) return val[rt] = l, void();
int mid = (l + r) >> 1;
build(l, mid, ls), build(mid + 1, r, rs);
}
void update(int tl, int tr, int c, int l = 1, int r = n, int rt = 1) {
if (tl <= l && r <= tr) return cover[rt] = c, val[rt] = c, void();
int mid = (l + r) >> 1;
pushdown(rt);
if (tl <= mid) update(tl, tr, c, l, mid, ls);
if (tr > mid) update(tl, tr, c, mid + 1, r, rs);
}
int query(int x, int l = 1, int r = n, int rt = 1) {
if (l == r) return val[rt];
int mid = (l + r) >> 1;
pushdown(rt);
if (x <= mid) return query(x, l, mid, ls);
return query(x, mid + 1, r, rs);
}
void _main() {
read(n, q);
fill(cnt + 1, cnt + n + 1, 1);
build(1, n, 1);
while (q--) {
read(opt, x);
if (opt == 1) {
read(c);
int l = L.find(x), r = R.find(x);
cnt[query(l)] -= r - l + 1;
update(l, r, c);
cnt[c] += r - l + 1;
if (l != 1 && query(l - 1) == c) L.fa[l] = L.find(l - 1), R.fa[l - 1] = R.find(l);
if (r != n && query(r + 1) == c) L.fa[r + 1] = L.find(r), R.fa[r] = R.find(r + 1);
} else if (opt == 2) {
writeln(cnt[x]);
}
}
flush();
} signed main() {
ios::sync_with_stdio(false);
cin.tie(nullptr), cout.tie(nullptr), cerr.tie(nullptr);
int t = 1; for (/*cin >> t*/; t--; ) _main();
return 0;
}