https://ac.nowcoder.com/acm/contest/9983/E
有n个礼物,每个礼物都有不同的编号,下面有m次操作
看一眼单点修改区间查询,然后转换一下题意变成找区间出现最多的数
咦~这不是分块or莫队轻松解决
然后瞄一眼数据范围5e5,优雅暴力 基本是没戏
题解给了一种非常巧的解法,用链表链接前后两个编号相同的点,然后在查询区间中是否存在两个相同的编号就可以转化为[l, r]中有一个点的后继下标小于r,这样就完美符合要求
所以我们只要区间内最小值满足小于r即可,就是一个简单的rmq问题
至于链表的处理,两个数组前后各扫一遍即可
#pragma GCC optimize(2)
#include
using namespace std;
//#define ACM_LOCAL
#define fi first
#define se second
const int N = 1e6 + 10;
const int M = 5e5 + 10;
const int INF = 0x3f3f3f3f;
const double eps = 1e-4;
const int MOD = 1e9+7;
typedef long long ll;
typedef pair<int, int> PII;
int a[N], vis[N], nxt[N], pre[N];
struct node {
int l, r;
int sum;
}t[N<<2];
void push_up(int u) {
t[u].sum = min(t[u<<1].sum, t[u<<1|1].sum);
}
void build(int u, int l, int r) {
t[u].l = l, t[u].r = r;
if (l == r) {
t[u].sum = nxt[l];
return;
}
int mid = (l + r) >> 1;
build(u<<1, l, mid);
build(u<<1|1, mid+1, r);
push_up(u);
}
void modify(int u, int pos, int val) {
if (t[u].l == t[u].r) {
t[u].sum = val;
return;
}
int mid = (t[u].l + t[u].r) >> 1;
if (pos <= mid) modify(u<<1, pos, val);
else modify(u<<1|1, pos, val);
push_up(u);
}
int query(int u, int ql, int qr) {
if (ql <= t[u].l && qr >= t[u].r) return t[u].sum;
int mid = (t[u].l + t[u].r) >> 1;
int Min = INF;
if (ql <= mid) Min = min(Min, query(u<<1, ql, qr));
if (qr > mid) Min = min(Min, query(u<<1|1, ql, qr));
return Min;
}
void solve() {
int n, m; cin >> n >> m;
for (int i = 1; i <= n; i++) nxt[i] = n+1, pre[i] = 0;
for (int i = 1; i <= n; i++) cin >> a[i];
for (int i = n; i >= 1; i--) {
if (vis[a[i]]) nxt[i] = vis[a[i]];
vis[a[i]] = i;
}
memset(vis, 0, sizeof vis);
for (int i = 1; i <= n; i++) {
if (vis[a[i]]) pre[i] = vis[a[i]];
vis[a[i]] = i;
}
build(1, 1, n);
while (m--) {
int opt, x, y; cin >> opt;
if (opt == 1) {
cin >> x;
modify(1, x, INF);
modify(1, pre[x], nxt[x]);
nxt[pre[x]] = nxt[x]; //前继指向后继
pre[nxt[x]] = pre[x]; //后继指向前继
} else {
cin >> x >> y;
int tmp = query(1, x, y);
if (tmp <= y) printf("1\n");
else printf("0\n");
}
}
}
signed main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
#ifdef ACM_LOCAL
freopen("input", "r", stdin);
freopen("output", "w", stdout);
#endif
solve();
}