SPOJ 3267. D-query (主席树)
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SPOJ 3267. D-query (主席树)相关的知识,希望对你有一定的参考价值。
A - D-query
Time Limit:1500MS Memory Limit:0KB 64bit IO Format:%lld & %lluGiven 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
(其实我觉得这道题作为主席树入门比第k大数要好很多)
大概就是从前往后,插入一个数则新建一棵树,如果之前没有出现,直接插入,如果之前出现了 ,再建一棵树删除,大概是这样。
(我说新建一棵树不是真的新建诶,学了主席树应该大概知道我的意思)
1 #include <bits/stdc++.h> 2 3 using namespace std; 4 const int N = 30000 + 11 ; 5 6 int n,a[N],li[N],q,tot,cnt,root[N],pos[N]; 7 struct id 8 { 9 int l,r,sum; 10 }tree[N*40]; 11 12 13 void Init() 14 { 15 scanf("%d",&n); 16 for(int i = 1; i <= n; ++i) 17 { 18 scanf("%d",a + i); 19 li[i] = a[i]; 20 } 21 sort(li+1,li+1+n); 22 tot = 1 ; 23 for(int i = 2 ; i <= n; ++i) if( li[i] != li[tot] ) li[++tot] = li[i]; 24 } 25 26 int binary_search( int num ) 27 { 28 int l = 1 , r = tot; 29 while( l <= r ) 30 { 31 int mid = l + ((r-l)>>1); 32 if(li[mid] == num) return mid; 33 if(li[mid] < num) l = mid + 1; 34 else r = mid - 1; 35 } 36 return -1; 37 } 38 39 void updata(int l,int r,int &x,int y,int posi,int add) 40 { 41 tree[++cnt] = tree[y] ; x = cnt; tree[cnt].sum += add; 42 if(l == r) return ; 43 int mid = l + ((r-l)>>1); 44 if(posi <= mid) updata(l,mid,tree[x].l,tree[y].l,posi,add); 45 else updata(mid+1,r,tree[x].r,tree[y].r,posi,add); 46 } 47 48 int query( int num,int L,int R,int l,int r ) 49 { 50 if(L ==l && R == r) return tree[num].sum; 51 int mid = L + ((R-L)>>1); 52 if(r <= mid) return query(tree[num].l,L,mid,l,r); 53 else if(l > mid) return query(tree[num].r,mid+1,R,l,r); 54 else return query(tree[num].l,L,mid,l,mid) + query(tree[num].r,mid+1,R,mid+1,r); 55 } 56 57 void Solve( ) 58 { 59 for(int i = 1 ; i <= n; ++i) 60 { 61 int num = binary_search(a[i]); 62 updata(1,n,root[i],root[i-1],i,1); 63 if( pos[num] ) updata(1,n,root[i],root[i],pos[num],-1); 64 pos[num] = i; 65 } 66 scanf("%d",&q); 67 for(int i = 1 ; i <= q; ++i) 68 { 69 int l, r; 70 scanf("%d%d",&l,&r); 71 printf("%d\n",query(root[r],1,n,l,r)); 72 } 73 } 74 75 int main( ) 76 { 77 // freopen("spoj3267.in","r",stdin); 78 // freopen("spoj3267.out","w",stdout); 79 Init(); 80 Solve(); 81 fclose(stdin); 82 fclose(stdout); 83 return 0; 84 }
以上是关于SPOJ 3267. D-query (主席树)的主要内容,如果未能解决你的问题,请参考以下文章
SPOJ 3267 D-query(离散化+主席树求区间内不同数的个数)