主席树,每个点建一个线段树
查看原帖
主席树,每个点建一个线段树
93807
zgb666楼主2024/4/11 14:40
//#include<bits/stdc++.h>
#include<iostream>
#include<cstring>
using namespace std;
const int maxn=1e5+7;
int ls[maxn*50],rs[maxn*50],cnt,s[maxn*50],root[maxn];
int t,n,q;
void pushup(int k){
	s[k]=s[ls[k]]+s[rs[k]];
}
inline void change(int &k,int pre,int le,int ri,int x){//动态开点权值线段树 
	k=++cnt;
	ls[k]=ls[pre];rs[k]=rs[pre];s[k]=s[pre]; 
	if(le==ri){
		s[k]++;	return;
	}	
	int mid=(le+ri)/2;
	if(x<=mid) change(ls[k],ls[pre],le,mid,x);
	else change(rs[k],rs[pre],mid+1,ri,x);
//	pushup(k);
}
inline int find(int k,int pre,int le,int ri,int x){//区间查询数据 
	if(le==ri){
		return s[k]-s[pre];
	}
	int mid=(le+ri)/2;
	if(x<=mid) return find(ls[k],ls[pre],le,mid,x);
	else return find(rs[k],rs[pre],mid+1,ri,x);
}
void clear(){//清除历史记录 
	memset(ls,0,sizeof(ls));
	memset(rs,0,sizeof(rs));
	memset(s,0,sizeof(s));
	memset(root,0,sizeof(root));
	cnt=0;
}
int main(){
	cin>>t;
	while(t--){
		clear();
		cin>>n;
		for(int i=1;i<=n;i++){
			int x;scanf("%d",&x);
			change(root[i],root[i-1],1,1e9,x);
		}
		scanf("%d",&q);
		while(q--){
			int x,y,c,r;
			scanf("%d%d%d",&x,&y,&c);
			r=find(root[y],root[x-1],1,1e9,c);
//			cout<<find(root[y],root[x-1],1,1e9,c)<<endl;
			printf("%d\n",r);
			
		}
	}
	return 0;
}
2024/4/11 14:40
加载中...