您的位置:首页 > 产品设计 > UI/UE

SPOJ-DQUERY-主席树求区间不同数个数模板

2015-08-06 22:44 489 查看
A - D-query
Time Limit:227MS Memory Limit:1572864KB 64bit IO Format:%lld
& %llu
SubmitStatusPracticeSPOJ
DQUERY

Appoint description:

Description

EnglishVietnamese
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


题目大意:求一个区间有多少数不相同。

思路;主席树用第i棵线段树表示右区间r因为第r棵线段树总共才插入1到r个数,然后l到r的区间不同数的个数就是第r棵线段树l到r的数的总和。

#include <cstdio>
#include <cstring>
#include <cmath>
#include <queue>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 100005;
int lson[maxn*30],rson[maxn*30],c[maxn*30],T[maxn];
int a[maxn],b[maxn],len,tot,vis[maxn],n;
void hase(int k)
{
sort(b,b+k);
len = unique(b,b+k) - b;
}
int get_hase(int k)
{
return (lower_bound(b,b+len,k) - b);
}
int build(int l,int r)
{
int root = tot++;
c[root] = 0;
if(l != r)
{
int mid = (l +r) >> 1;
lson[root] = build(l,mid);
rson[root] = build(mid + 1,r);
}
return root;
}
int insert1(int root,int pos,int val)
{
int newroot = tot++;
int tmp = newroot;
c[newroot] = c[root] + val;
int l = 1, r = n;
while(l < r)
{
int mid = (l + r) >> 1;
if(pos <= mid)
{
lson[newroot] = tot++;
rson[newroot] = rson[root];
newroot = lson[newroot];
root = lson[root];
r = mid;
}
else
{
lson[newroot] = lson[root];
rson[newroot] = tot++;
newroot = rson[newroot];
root = rson[root];
l = mid +1;
}
c[newroot] = c[root] + val;
}
return tmp;
}
int A,B;
int qurry(int root,int l, int r)
{
if(A<= l && r <= B)
{
return c[root];
}
int mid = (l + r) >> 1;
int ans = 0;
if(A <= mid) ans += qurry(lson[root],l,mid);
if(B > mid) ans += qurry(rson[root],mid + 1, r);
return ans;
}
int main()
{
while(scanf("%d",&n) != EOF)
{
len = tot = 0;
memset(vis,-1,sizeof(vis));
int i;
for(i = 1; i <= n; i++)
{
scanf("%d",&a[i]);
b[len++] = a[i];
}
hase(len);
T[0] = build(1,n);
for(i = 1;i <= n; i++)
{
int tmp = T[i-1];
int vv = get_hase(a[i]);
if(vis[vv] != -1)
{
tmp = insert1(T[i-1],vis[vv],-1);
}
T[i] = insert1(tmp,i,1);
vis[vv] = i;
}
int m;
scanf("%d",&m);
while(m--)
{
int q,w;
scanf("%d %d",&A,&w);
B = n;
printf("%d\n",qurry(T[w],1,n));
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: