P3901 数列找不同(洛谷)(莫队板子题)
题目链接:点我
时间限制
1.00s
内存限制
125.00MB
题目描述
现有数列 A 1 , A 2 , … , A N A_1,A_2,\ldots,A_N A1,A2,…,AN , Q Q Q 个询问 ( L i , R i ) (L_i,R_i) (Li,Ri),询问 A L i , A L i + 1 , … , A R i A_{L_i} ,A_{L_i+1},\ldots,A_{R_i} ALi,ALi+1,…,ARi是否互不相同。
输入格式
第一行,两个整数
N
,
Q
N,Q
N,Q。
第二行,
N
N
N 个整数
A
1
,
A
2
,
…
,
A
N
A_1, A_2, \ldots , A_N
A1,A2,…,AN。
接下来
Q
Q
Q 行,每行两个整数
L
i
,
R
i
L_i,R_i
Li,Ri。
输出格式
对每个询问输出一行,Yes
或 No
。
输入输出样例
输入 #1 复制
4 2
1 2 3 2
1 3
2 4
输出 #1 复制
Yes
No
说明/提示
对于
50
%
50\%
50% 的数据,
N
,
Q
≤
1
0
3
N,Q \le 10^3
N,Q≤103。
对于
100
%
100\%
100% 的数据,
1
≤
N
,
Q
≤
1
0
5
,
1
≤
A
i
≤
N
,
1
≤
L
i
≤
R
i
≤
N
1 \le N,Q \le 10^5,1 \le A_i \le N,1 \le L_i \le R_i \le N
1≤N,Q≤105,1≤Ai≤N,1≤Li≤Ri≤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;
}