zoukankan      html  css  js  c++  java
  • SPOJ3267--D-query (主席树入门练习)

    题意:查找区间内不同数字的个数。

    两种做法,一种是 树状数组离线,另一种就是主席树。

    树状数组离线操作的链接 http://www.cnblogs.com/oneshot/p/4110415.html

    两种方法思路差不多,都是扫一遍,如果这个数曾经出现过那么就 在上次位置-1,如果没有出现过就在 当前位置+1,同时更新该数字的最新的位置。

    这样的话,在主席树里面 以x为根的线段树存的就是1-x之间不同的数字的个数。我们只需要查找以r为根的线段树同时大于l的区间内的个数就行了。

    给主席跪了,orz。主席树其实就是每个位置对应一颗线段树,但是这样 n 个点 n 棵线段树显然会MLE,怎么解决呢?我们可以看到 从第 i 棵线段树到第i+1 棵线段树,很多子树都是相同的,这样如果再重新建一棵完整的线段树显然浪费了很大的空间。我们只需要把第i棵线段树的 某个子树同时第i+1棵线段树 某个 节点下面即可,这样就大大减小了空间复杂度。

      1 #include <map>
      2 #include <cstdio>
      3 #include <vector>
      4 #include <cstdlib>
      5 #include <cstring>
      6 #include <algorithm>
      7 using namespace std;
      8 const int maxn = 3e4+10;
      9 int a[maxn],c[maxn*18],lson[maxn*18],rson[maxn*18],tot,n,m;
     10 int build(int l,int r)
     11 {
     12     int root = tot++;
     13     c[root] = 0;
     14     if (l != r)
     15     {
     16         int mid = (l + r) >> 1;
     17         lson[root] = build(l,mid);
     18         rson[root] = build(mid + 1,r);
     19     }
     20     return root;
     21 }
     22 int update(int root,int pos,int val)
     23 {
     24     int newroot = tot++;
     25     int tmp = newroot;
     26     c[newroot] = c[root] + val;
     27     int l = 1,r = n;
     28     while (l < r)
     29     {
     30         int mid = (l + r) >> 1;
     31         if (pos <= mid)
     32         {
     33             rson[newroot] = rson[root];
     34             lson[newroot] = tot++;
     35             newroot = lson[newroot];
     36             root = lson[root];
     37             r = mid;
     38         }
     39         else
     40         {
     41             lson[newroot] = lson[root];
     42             rson[newroot] = tot++;
     43             newroot = rson[newroot];
     44             root = rson[root];
     45             l = mid + 1;
     46         }
     47         c[newroot] = c[root] + val;
     48     }
     49     return tmp;
     50 }
     51 int query(int root,int pos)
     52 {
     53     int res = 0;
     54     int l = 1,r = n;
     55     while (pos > l)
     56     {
     57         int mid = (l + r) >> 1;
     58         if (pos <= mid)
     59         {
     60             res += c[rson[root]];
     61             root = lson[root];
     62             r = mid;
     63         }
     64         else
     65         {
     66             root = rson[root];
     67             l = mid + 1;
     68         }
     69     }
     70     return res + c[root];
     71 }
     72 int per_root[maxn];
     73 int main(void)
     74 {
     75     #ifndef ONLINE_JUDGE
     76         freopen("in.txt","r",stdin);
     77     #endif
     78     while (~scanf ("%d",&n))
     79     {
     80         tot = 0;
     81         for (int i = 1; i <= n ;i++)
     82             scanf ("%d",a+i);
     83         per_root[0] = build(1,n);
     84         map<int,int>mp;
     85         for (int i = 1; i <= n; i++)
     86         {
     87             if (mp.find(a[i]) == mp.end())
     88             {
     89                 per_root[i] = update(per_root[i-1],i,1);
     90             }
     91             else
     92             {
     93                 int tmp = update(per_root[i-1],mp[a[i]],-1);
     94                 per_root[i] = update(tmp,i,1);
     95             }
     96             mp[a[i]] = i;
     97         }
     98         scanf ("%d",&m);
     99         for (int i = 0; i < m; i++)
    100         {
    101             int l,r;
    102             scanf ("%d%d",&l,&r);
    103             printf("%d
    ",query(per_root[r],l));
    104         }
    105     }
    106     return 0;
    107 }
  • 相关阅读:
    Can't remove netstandard folder from output path (.net standard)
    website项目的reference问题
    The type exists in both DLLs
    git常用配置
    Map dependencies with code maps
    How to check HTML version of any website
    Bootstrap UI 编辑器
    网上职位要求对照
    Use of implicitly declared global variable
    ResolveUrl in external JavaScript file in asp.net project
  • 原文地址:https://www.cnblogs.com/oneshot/p/4112825.html
Copyright © 2011-2022 走看看