• SPOJ 3267. D-query (主席树,查询区间有多少个不相同的数)


    3267. D-query

    Problem code: DQUERY

    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 
    

    主席树的入门题了

      1 /* ***********************************************
      2 Author        :kuangbin
      3 Created Time  :2013-9-5 23:54:37
      4 File Name     :F:2013ACM练习专题学习主席树SPOJ_DQUERY.cpp
      5 ************************************************ */
      6 
      7 #include <stdio.h>
      8 #include <string.h>
      9 #include <iostream>
     10 #include <algorithm>
     11 #include <vector>
     12 #include <queue>
     13 #include <set>
     14 #include <map>
     15 #include <string>
     16 #include <math.h>
     17 #include <stdlib.h>
     18 #include <time.h>
     19 using namespace std;
     20 
     21 /*
     22  * 给出一个序列,查询区间内有多少个不相同的数
     23  */
     24 const int MAXN = 30010;
     25 const int M = MAXN * 100;
     26 int n,q,tot;
     27 int a[MAXN];
     28 int T[M],lson[M],rson[M],c[M];
     29 int build(int l,int r)
     30 {
     31     int root = tot++;
     32     c[root] = 0;
     33     if(l != r)
     34     {
     35         int mid = (l+r)>>1;
     36         lson[root] = build(l,mid);
     37         rson[root] = build(mid+1,r);
     38     }
     39     return root;
     40 }
     41 int update(int root,int pos,int val)
     42 {
     43     int newroot = tot++, tmp = newroot;
     44     c[newroot] = c[root] + val;
     45     int l = 1, r = n;
     46     while(l < r)
     47     {
     48         int mid = (l+r)>>1;
     49         if(pos <= mid)
     50         {
     51             lson[newroot] = tot++; rson[newroot] = rson[root];
     52             newroot = lson[newroot]; root = lson[root];
     53             r = mid;
     54         }
     55         else
     56         {
     57             rson[newroot] = tot++; lson[newroot] = lson[root];
     58             newroot = rson[newroot]; root = rson[root];
     59             l = mid+1;
     60         }
     61         c[newroot] = c[root] + val;
     62     }
     63     return tmp;
     64 }
     65 int query(int root,int pos)
     66 {
     67     int ret = 0;
     68     int l = 1, r = n;
     69     while(pos < r)
     70     {
     71         int mid = (l+r)>>1;
     72         if(pos <= mid)
     73         {
     74             r = mid;
     75             root = lson[root];
     76         }
     77         else
     78         {
     79             ret += c[lson[root]];
     80             root = rson[root];
     81             l = mid+1;
     82         }
     83     }
     84     return ret + c[root];
     85 }
     86 
     87 int main()
     88 {
     89     //freopen("in.txt","r",stdin);
     90     //freopen("out.txt","w",stdout);
     91     while(scanf("%d",&n) == 1)
     92     {
     93         tot = 0;
     94         for(int i = 1;i <= n;i++)
     95             scanf("%d",&a[i]);
     96         T[n+1] = build(1,n);
     97         map<int,int>mp;
     98         for(int i = n;i>= 1;i--)
     99         {
    100             if(mp.find(a[i]) == mp.end())
    101             {
    102                 T[i] = update(T[i+1],i,1);
    103             }
    104             else
    105             {
    106                 int tmp = update(T[i+1],mp[a[i]],-1);
    107                 T[i] = update(tmp,i,1);
    108             }
    109             mp[a[i]] = i;
    110         }
    111         scanf("%d",&q);
    112         while(q--)
    113         {
    114             int l,r;
    115             scanf("%d%d",&l,&r);
    116             printf("%d
    ",query(T[l],r));
    117         }
    118     }
    119     return 0;
    120 }
  • 相关阅读:
    java两个栈实现一个队列&&两个队列实现一个栈
    Java HashSet和ArrayList的查找Contains()时间复杂度
    Java KMP算法代码
    利用集合求取字符串里每个字符的个数
    快速失败and安全失败
    Java 巴什博弈(取石子报数问题)
    [知识点][施工中] 1.1 部分IDE介绍
    [知识点] 4.4 动态规划进阶模型——树形/DAG/数位DP
    [知识点] 4.3 动态规划基础模型——区间DP/LIS/LCS
    [课堂小笔记] 数字电子技术
  • 原文地址:https://www.cnblogs.com/kuangbin/p/3305212.html
Copyright © 2020-2023  润新知