11071: 小P的太空旅行
时间限制: 1 Sec 内存限制: 128 MB
提交: 78 解决: 27
[提交] [状态] [讨论版] [命题人:admin]
题目描述
今年是8102年,小P去M870星球旅行了。M870星球景色优美,食物非常美味,所以全宇宙的人都爱去M870星球旅行。
这些来旅行的游客可以看作一排,来自不同星球的旅客的识别码是不同的,识别码是由1到k的,不同识别码表示不同星球的旅客。
小P想要知道,在一个区间里有多少种出现次数恰好为T次的旅客。
输入
第一行四个整数n,m,k,T(1<=n,m,k,T<=5*10^5)。
第二行n个整数,第i个整数为a[i],表示对应旅客的种族(1<=a[i]<=k)。
接下来m行,每行两个整数l[i]和r[i],表示询问的区间(1<=l[i]<=r[i]<=n)。
输出
输出m行,每行一个整数,第i行表示第i次询问的答案。
样例输入
复制样例数据
10 5 5 1
1 5 3 4 2 4 1 2 3 5
1 10
3 6
2 8
5 7
6 10
样例输出
0
2
3
3
5
提示
对于30%的数据 n,m,k<=2000,T<=n.
对于另外40%的数据 T=1,1<=n,m,k<=5*10^5.
对于所有数据,1<=n,m,k,T<=5*10^5,1<=a[i]<=k,1<=l[i]<=r[i]<=n.
注意:本题输入量较大,请使用较为快速的读入方式。
题面看起来就像是莫队,结果当时居然没想到,头秃
唉,就当时再复习一遍莫队好了
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 5e5 + 100;
struct node {
int l, r, id;
} s[maxn];
int a[maxn];
int qt, val, t;
int ans[maxn];
int num[maxn];
bool cmp(node a, node b) {
if (a.l / qt == b.l / qt) return a.r < b.r;
return a.l / qt < b.l / qt;
}
void update(int x, int v) {
if (num[a[x]] == t) val--;
num[a[x]] += v;
if (num[a[x]] == t) val++;
}
int main() {
int n, m, k;
scanf("%d%d%d%d", &n, &m, &k, &t);
qt = sqrt(n);
for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
for (int i = 1; i <= m; i++) {
scanf("%d%d", &s[i].l, &s[i].r);
s[i].id = i;
}
sort(s + 1, s + m + 1, cmp);
int l = 1, r = 0;
for (int i = 1; i <= m; i++) {
while (l < s[i].l) update(l++, -1);
while (l > s[i].l) update(--l, 1);
while (r < s[i].r) update(++r, 1);
while (r > s[i].r) update(r--, -1);
ans[s[i].id] = val;
}
for (int i = 1; i <= m; i++) printf("%d\n", ans[i]);
return 0;
}