[主席树]HDOJ3874 Necklace

题意:n个数 m个询问

询问的是[l, r]区间内不同的数的和

没有修改,静态的主席树即可

SPOJ QUERY 一样 将重复的元素建树即可

注意范围:$N le  50000$ 每个值不超过1000000

也就是加起来会爆int 要用LL

  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 typedef long long LL;
  4 #define lson l, m
  5 #define rson m+1, r
  6 const int N=5e4+5;
  7 
  8 int L[N<<5], R[N<<5];
  9 LL sum[N<<5];
 10 int tot;
 11 int a[N], T[N];
 12 int read()
 13 {
 14     char ch=' ';
 15     int ans=0;
 16     while(ch<'0' || ch>'9')
 17         ch=getchar();
 18     while(ch<='9' && ch>='0')
 19     {
 20         ans=ans*10+ch-'0';
 21         ch=getchar();
 22     }
 23     return ans;
 24 }
 25 
 26 int build(int l, int r)
 27 {
 28     int rt=(++tot);
 29     sum[rt]=0;
 30     if(l<r)
 31     {
 32         int m=(l+r)>>1;
 33         L[rt]=build(lson);
 34         R[rt]=build(rson);
 35     }
 36     return rt;
 37 }
 38 
 39 int update(int pre, int l, int r, int x, int val)
 40 {
 41     int rt=(++tot);
 42     L[rt]=L[pre], R[rt]=R[pre], sum[rt]=sum[pre]+val;
 43     if(l<r)
 44     {
 45         int m=(l+r)>>1;
 46         if(x<=m)
 47             L[rt]=update(L[pre], lson, x, val);
 48         else
 49             R[rt]=update(R[pre], rson, x, val);
 50     }
 51     return rt;
 52 }
 53 
 54 LL query(int u, int v, int l, int r, int k)
 55 {
 56      if(l>=k)
 57         return sum[v]-sum[u];
 58     int m=(l+r)>>1;
 59     LL ans=0;
 60     if(m>=k)
 61         ans+=query(L[u], L[v], lson, k);
 62     ans+=query(R[u], R[v], rson, k);
 63     return ans;
 64 }
 65 
 66 LL all[N];
 67 int main()
 68 {
 69     int t;
 70     scanf("%d", &t);
 71     while(t--)
 72     {
 73         tot=0;
 74         int n=read();
 75 //        scanf("%d", &n);
 76         all[0]=0;
 77         for(int i=1; i<=n; i++)
 78         {
 79 //            scanf("%d", &a[i]);
 80             a[i]=read();
 81             all[i]=all[i-1]+a[i];
 82         }
 83            T[0]=0;
 84         map<int, int> mp;
 85         mp.clear();
 86         for(int i=1; i<=n; i++)
 87         {
 88             if(mp.find(a[i])!=mp.end())
 89                 T[i]=update(T[i-1], 1, n, mp[a[i]], a[i]);
 90             else
 91                 T[i]=T[i-1];
 92             mp[a[i]]=i;
 93         }
 94         int m=read();
 95 //        scanf("%d", &m);
 96         while(m--)
 97         {
 98             int l, r;
 99             l=read(), r=read();
100 //            scanf("%d%d", &l, &r);
101             printf("%I64d
", all[r]-all[l-1]-query(T[l-1], T[r], 1, n, l));
102         }
103     }
104     return 0;
105 }
HDOJ 3874
原文地址:https://www.cnblogs.com/Empress/p/4675397.html