P10288 [GESP样题 八级] 区间

题目背景

小杨有一个长度为 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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值