Spoj DQUERY D-query (主席树模板)

DQUERY - D-query


Given a sequence of n numbers a1, a2, ..., an and a number of d-queries. A d-query is a pair (i, j) (1 ≤ i ≤ j ≤ n). For each d-query (i, j), you have to return the number of distinct elements in the subsequence ai, ai+1, ..., aj.

Input

  • Line 1: n (1 ≤ n ≤ 30000).
  • Line 2: n numbers a1, a2, ..., an (1 ≤ ai ≤ 106).
  • Line 3: q (1 ≤ q ≤ 200000), the number of d-queries.
  • In the next q lines, each line contains 2 numbers i, j representing a d-query (1 ≤ i ≤ j ≤ n).

Output

  • For each d-query (i, j), print the number of distinct elements in the subsequence ai, ai+1, ..., aj in a single line.

Example

Input
5
1 1 2 1 3
3
1 5
2 4
3 5

Output
3
2
3 
 
 

/*
题意:给n个数,m次查询,求[l,r]之间不重复的个数

思路:主席树,利用spos记录每个值在当前操作下最新
	的位置,从前往后插入主席树(不需要离散),对于
	查询[l,r],我们只要用root[r]的r减去root[r]的l
	的个数就可以了。 
*/

#include<bits/stdc++.h>

using namespace std;
const int maxn = 1e6+10;
int a[maxn],root[maxn],spos[maxn];
int n,m,cnt;
vector<int> v;

struct node{
	int l,r,sum;
}T[maxn*25];

void update(int l,int r,int &x,int y,int pos,int add){
	T[++cnt]=T[y];
	T[cnt].sum+=add;
	x=cnt;						//修改root[i]所指的根节点 
	if(l==r) return ;   		//更新完成
	int mid = (l+r)>>1;
	if(mid >= pos) update(l,mid,T[x].l,T[y].l,pos,add);  
	else update(mid+1 ,r ,T[x].r,T[y].r,pos,add);
}

int query(int l,int r,int x,int pos){
	if(l==r) return T[x].sum;
	int mid = (l+r)>>1;
	int res=0;
	if(mid >= pos){
		res=query(l,mid,T[x].l,pos);
	}else{
		res+=T[T[x].l].sum;
		res+=query(mid+1,r,T[x].r,pos);
	}
	return res;
}

int main(){
	int l,r;
	v.clear();
	memset(spos,0,sizeof spos);
	cnt=0;
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		scanf("%d",&a[i]);
		v.push_back(a[i]);
	}
	
	for(int i=1;i<=n;i++){
		update(1,n,root[i],root[i-1],i,1);
		if(spos[a[i]]!=0) update(1,n,root[i],root[i],spos[a[i]],-1);//将第i的版本之前重复的相应位置减去 
		spos[a[i]]=i;
	}
	scanf("%d",&m);
	for(int i=0;i<m;i++){
		scanf("%d%d",&l,&r);
		if(l==1) printf("%d\n",query(1,n,root[r],r));			//注意点,query二分不完善 
		else {
			//root只能通过第r个求出与前面第1到r-1的不同个数 
			int ans=query(1,n,root[r],r)-query(1,n,root[r],l-1);
			printf("%d\n",ans);
		}
	}
} 

猜你喜欢

转载自blog.csdn.net/rvelamen/article/details/80754813