l~r区间查找等于k的数有多少个(主席树)

/*
https://ac.nowcoder.com/acm/contest/917/H
n个数 m个询问(m,n<1e4) 这个n个数是大于等于0的 
询问l ---  r有多少等于k的值

题解:可以把a[i]当成下标 i当成数组 
 
*/
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+100;
const int mod=20180623;
int a[N];
vector<int>vec[N];

int main()
{
	int n,m;
	scanf("%d %d",&n,&m);
	for(int i=1;i<=n;i++){
		scanf("%d",&a[i]);
		vec[a[i]].push_back(i);
	}
	while(m--){
		int l1,r1,l2,r2,k;
		scanf("%d %d %d %d %d",&l1,&r1,&l2,&r2,&k);
		if(l1>r1) swap(l1,r1);
		if(l2>r2) swap(l2,r2);
		long long x=upper_bound(vec[k].begin(),vec[k].end(),r1)-lower_bound(vec[k].begin(),vec[k].end(),l1);
		long long y=upper_bound(vec[k].begin(),vec[k].end(),r2)-lower_bound(vec[k].begin(),vec[k].end(),l2);
		printf("%lld\n",x%mod);
		printf("%lld\n",y%mod);
		printf("%lld\n",((x%mod)*(y%mod))%mod);
	}
	return 0;
} 
/*
当这个n个数不一定大于0时
那么可以用主席树做  这里运行到了求区间第k大的思想
可以和上面那个二分的思想联系一下  
*/
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
const int mod= 20180623;
struct node
{
	int l,r,sum;
}tree[N*20];
int root[N],a[N];
int cnt;
void build(int &now,int l,int r)
{
	now=++cnt;
	if(l==r){
		tree[now].sum=0;
		return;
	}
	int mid=(l+r)>>1;
	build(tree[now].l,l,mid); 
	build(tree[now].r,mid+1,r);
}
void update(int &x,int y,int l,int r,int pos)
{
	x=++cnt;
	tree[x]=tree[y];
	tree[x].sum++;
	if(l==r) return;
	int mid=(l+r)>>1;
	if(pos<=mid) update(tree[x].l,tree[y].l,l,mid,pos);
	else update(tree[x].r,tree[y].r,mid+1,r,pos); 
}
int query(int x,int y,int val,int l,int r)
{
	
	if(l==r) return tree[y].sum-tree[x].sum;
	int mid=(l+r)>>1;
	if(val<=mid) return query(tree[x].l,tree[y].l,val,l,mid);
	else return query(tree[x].r,tree[y].r,val,mid+1,r);
}
int main()
{
 	int n,m;
 	scanf("%d %d",&n,&m);
 	build(root[0],1,10000);
 	int maxn=0;
 	for(int i=1;i<=n;i++){
 		int x;scanf("%d",&x);
 		maxn=max(maxn,x);
 		update(root[i],root[i-1],1,10000,x);
 	}
 	while(m--){
 		int l1,r1,l2,r2,k;
 		scanf("%d %d %d %d %d",&l1,&r1,&l2,&r2,&k);
 		if(l1>r1) swap(l1,r1);
 		if(l2>r2) swap(l2,r2);
 		if(k>maxn){
 			printf("0\n0\n0\n");
 			continue;
 		}
 		long long x=query(root[l1-1],root[r1],k,1,10000);
 		long long y=query(root[l2-1],root[r2],k,1,10000);
 		printf("%lld\n%lld\n%lld\n",x,y,(x*y)%mod);
 	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/CC_1012/article/details/92180528