题目背景
小杨有一个长度为 nn 的正整数序列 AA。
题目描述
小杨有一个长度为 nn 的正整数序列 AA。
小杨有 qq 次询问。第 ii 次(1≤i≤q1≤i≤q)询问时,小杨会给出 li,ri,xili,ri,xi,请你求出 xixi 在 Ali,Ali+1,…AriAli,Ali+1,…Ari 中出现的次数。
输入格式
第一行包含一个正整数 TT,表示数据组数。
对于每组数据:第一行包含一个正整数 nn,表示序列 AA 的长度。
第二行包含 nn 个正整数 A1,A2,…,AnA1,A2,…,An,表示序列 AA。
第三行包含一个正整数 qq,表示询问次数。接下来 qq 行,每行三个正整数 li,ri,xili,ri,xi,表示一组询问。
输出格式
对于每组数据,输出 qq 行。第 ii 行(1≤i≤q1≤i≤q)输出一个非负整数,表示第 ii 次询问的答案。
输入输出样例
输入 #1
2 5 7 4 6 1 1 2 1 2 5 1 5 1 2 3 4 5 2 5 5 3 1 4 3
输出 #1
0 2 0 1
对于全部数据,保证有 1≤T≤51≤T≤5,1≤n,q≤1051≤n,q≤105,1≤Ai≤1091≤Ai≤109。
code
#include<bits/stdc++.h>
#define int long long
using namespace std;
int t,n,q,al,ar,x;
struct A {
int a,i;
} a[100005];
bool cmp(A a,A b) {
if(a.a!=b.a)return a.a<b.a;
else return a.i<b.i;
}
signed main() {
cin>>t;
while(t--) {
cin>>n;
for(int i=1; i<=n; i++)cin>>a[i].a,a[i].i=i;
sort(a+1,a+n+1,cmp);
cin>>q;
while(q--) {//二分查找区间
cin>>al>>ar>>x;
int l=1,r=n,sl=-1,sr=-1;
while(l<=r) {
int mid=(l+r)/2;
if(a[mid].a==x) {
if(a[mid].i==al) {
sl=mid;
break;
} else if(a[mid].i<al)l=mid+1;
else {
if(a[mid].i<=ar)sl=mid;
r=mid-1;
}
} else if(a[mid].a>x)r=mid-1;
else l=mid+1;
}
l=1,r=n;
while(l<=r) {
int mid=(l+r)/2;
if(a[mid].a==x) {
if(a[mid].i==ar) {
sr=mid;
break;
} else if(a[mid].i>ar)r=mid-1;
else {
if(a[mid].i>=al)sr=mid;
l=mid+1;
}
} else if(a[mid].a>x)r=mid-1;
else l=mid+1;
}
if(sl==-1||sr==-1)cout<<0<<"\n";
else cout<<sr-sl+1<<"\n";
}
}
return 0;
}
code