P3901 數列找不同(洛谷)(莫隊板子題)

P3901 數列找不同(洛谷)(莫隊板子題)

題目鏈接:點我
時間限制
1.00s
內存限制
125.00MB

題目描述

現有數列 A1,A2,,ANA_1,A_2,\ldots,A_NQQ 個詢問 (Li,Ri)(L_i,R_i),詢問 ALi,ALi+1,,ARiA_{L_i} ,A_{L_i+1},\ldots,A_{R_i}是否互不相同。

輸入格式

第一行,兩個整數N,QN,Q
第二行,NN 個整數A1,A2,,ANA_1, A_2, \ldots , A_N
接下來 QQ 行,每行兩個整數 Li,RiL_i,R_i

輸出格式

對每個詢問輸出一行,YesNo

輸入輸出樣例

輸入 #1 複製

4 2
1 2 3 2
1 3
2 4

輸出 #1 複製

Yes
No

說明/提示

對於 50%50\% 的數據,N,Q103N,Q \le 10^3
對於 100%100\% 的數據,1N,Q1051AiN1LiRiN1 \le N,Q \le 10^5,1 \le A_i \le N,1 \le L_i \le R_i \le N

題解

無題解

官方題解:點我

代碼

#include <bits/stdc++.h>
#define maxn 100005
#define _for(i, a) for(int i = 0; i < (a); ++i)
#define _rep(i, a, b) for(int i = (a); i <= (b); ++i)
#define mem0(a) memset(a, 0, sizeof(a))
#define sc(x) scanf("%d", &x)
using namespace std;
typedef long long LL;

struct poi {
	int l, r, id;
};

int n, q, a[maxn];
int ans[maxn];
poi lr[maxn];
int num[maxn];
int bl;

void init() {
	mem0(num);
}

struct cmpf {
	inline bool operator() (const poi &a, const poi &b) {
		return (a.l / bl) == (b.l / bl) ? a.r < b.r : a.l < b.l;
	}
};

void sol() {
	init();
	bl = sqrt(n);
	_rep(i, 1, n) sc(a[i]);
	_for(i, q) sc(lr[i].l), sc(lr[i].r), lr[i].id = i;
	sort(lr, lr + q, cmpf());
	int nl = 1, nr = 0, te = 0;
	_for(i, q) {
		int l = lr[i].l, r = lr[i].r;
		while (nl < l) if (--num[a[nl++]] > 0) --te;
		while (nl > l) if (++num[a[--nl]] > 1) ++te;
		while (nr < r) if (++num[a[++nr]] > 1) ++te;
		while (nr > r) if (--num[a[nr--]] > 0) --te;
		ans[lr[i].id] = (te > 0);
	}
	_for(i, q) printf("%s", ans[i] ? "No\n" : "Yes\n");
}

int main() {

	while (cin >> n >> q) {
		sol();
	}
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章