solution1(通过40%)
#include<iostream>
#include<map>
using namespace std;
int main(){
int n, m, a[100010], l, r, k, count;
scanf("%d", &n);
for(int i = 1; i <= n; i++)
scanf("%d", a + i);
scanf("%d", &m);
while(m--){
map<int, int> mp;
count = 0;
scanf("%d%d%d", &l, &r, &k);
for(int i = l; i <= r; i++)
mp[a[i]]++;
for(map<int, int>::iterator it = mp.begin(); it != mp.end(); it++){
if(it -> second == k) count++;
}
printf("%d\n", count);
}
return 0;
}
solution2
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
const int maxn = 1e5 + 10;
struct query{
int l, r, id, k;
}q[maxn];
int a[maxn];//存储原始数据、
int p[maxn];//p[i]存储第i个元素的块号
int cnt[maxn];//cnt[i]第i个元素的出现次数
int kn[maxn];//kn[i]存储恰好出现i次数的个数
int ans[maxn];//ans[i]第i次查询的答案
bool cmp(query q1, query q2){//先比较是否同块,不同则优先按照块号排序,相同则按照右边界r排序
return p[q1.l] == p[q2.l] ? q1.r < q2.r : p[q1.l] < p[q2.l];
}
void add(int pos){//增加元素
kn[cnt[a[pos]]]--;//记元素值a[pos]的出现次数为N,则出现N次的元素个数减一
cnt[a[pos]]++;//元素值a[pos]的出现次数更新为N+1
kn[cnt[a[pos]]]++;//出现N+1次的元素个数加一
}
void del(int pos){//移除元素
kn[cnt[a[pos]]]--;//出现N次的元素个数减一
cnt[a[pos]]--;//元素值a[pos]的出现次数更新为N-1
kn[cnt[a[pos]]]++;//出现N-1次的元素个数加一
}
int main(){
int n, m, b, l = 1, r = 0;
scanf("%d", &n);
b = sqrt(n);
for(int i = 1; i <= n; i++){
scanf("%d", a + i);
p[i] = (i - 1) / b + 1;//计算每个元素的所属块号
}
scanf("%d", &m);
for(int i = 1; i <= m; i++){
cin >> q[i].l >> q[i].r >> q[i].k;//用scanf()输入会有三个测试点运行错误
q[i].id = i;//记录查询编号
}
sort(q + 1, q + 1 + m, cmp);
for(int i = 1; i <= m; i++){//处理查询
while(l < q[i].l) del(l++);//删除[l, q[i].l - 1]区间内的元素
while(r > q[i].r) del(r--);//删除区间[q[i].r + 1, r]内的元素
while(l > q[i].l) add(--l);//增加区间[q[i].l, l-1]内的元素
while(r < q[i].r) add(++r);//增加区间[r+1, q[i].r]内的元素
ans[q[i].id] = kn[q[i].k]; //记录本区间的查询结果
}
for(int i = 1; i <= m; i++)
printf("%d\n", ans[i]);
return 0;
}