P3901 数列找不同 【莫队】

P3901 数列找不同

莫队:一种离线处理的优化暴力解法,时间复杂度在n * n^(1/2),会被卡常数,但是极为简单
推荐视频:莫队算法

点击查看代码
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int a[N];
int pos[N];
struct node {
	int l, r, k;
}t[N];
string s[N];
int cnt[N],sum;
void Add(int x) {
	cnt[a[x]]++;
	if (cnt[a[x]] == 1) sum++;
}
void Sub(int x) {
	cnt[a[x]]--;
	if (cnt[a[x]] == 0) sum--;
}
int main() {
	int n,m;
	cin >> n>>m;
	for (int i = 1; i <= n; i++) cin >> a[i];
	int siz = sqrt(n);
	for (int i = 1; i <= n; i++) {
		pos[i] = i / siz;//分区块
	}
	for (int i = 1; i <= m; i++) {
		cin >> t[i].l >> t[i].r;
		t[i].k = i;//离线处理
	}
	sort(t + 1, t + 1 + m, [](node a, node b) {
		return pos[a.l] == pos[b.l] ? a.r < b.r : pos[a.l] < pos[b.l];//排序,如果在一个区块以右端点排序,不在同一区块以区块顺序排序
		});
	int l = 1, r = 0;//初始化
	for (int i = 1; i <= m; i++) {
		while (t[i].l <  l) Add(--l);//目标点在左,跟新且加上当前点
		while (t[i].r > r) Add(++r);
		while (t[i].l > l) Sub(l++);//减去
		while (t[i].r < r) Sub(r--);
		if (t[i].r - t[i].l + 1 == sum) s[t[i].k] = "Yes";
		else s[t[i].k] = "No";
	}
	for (int i = 1; i <= m; i++) {
		cout << s[i] << '\n';
	}
	return 0;
}
posted @ 2023-10-04 18:32  不o凡  阅读(12)  评论(0)    收藏  举报