hdu3874

题解:

和上一题基本相同

插入的时候变一下数值

具体看http://www.cnblogs.com/xuanyiming/p/7921926.html

代码:

#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=50005;
typedef long long ll;
struct Tree
{
    ll num;
    int ls,rs;
}T[N*20];
int now,rt[N],la[N*20],n,m,cnt=1,x,y,k,a[N];
int build(int l,int r)
{
    now++;
    if (l==r)return now;
    int k=now,mid=(l+r)/2;
    if (l<=mid)T[k].ls=build(l,mid);
    if (mid<r)T[k].rs=build(mid+1,r);
    return k; 
}
int insert(int x,int l,int r,int s,int kk)
{
    now++;
    if (l==r)
     {
         T[now].num=T[x].num+kk;
         return now;
     }
    int k=now,mid=(l+r)/2;
    if (s<=mid)
     {
         T[k].ls=insert(T[x].ls,l,mid,s,kk);
         T[k].rs=T[x].rs;
     }
    else
     {
         T[k].ls=T[x].ls;
         T[k].rs=insert(T[x].rs,mid+1,r,s,kk);
     } 
    T[k].num=T[T[k].ls].num+T[T[k].rs].num;
    return k; 
}
ll find(int s,int x,int y,int l,int r)
{
    if (l>y||r<x)return 0;
    if (x<=l&&y>=r)return T[s].num;
    ll ans=0;
    int mid=(l+r)/2;
    if (x<=mid)ans+=find(T[s].ls,x,y,l,mid);
    if (y>mid)ans+=find(T[s].rs,x,y,mid+1,r);
    return ans;
}
int main()
{
    int cas;
    scanf("%d",&cas);
    while (cas--)
    {
    scanf("%d",&n);    
    memset(T,0,sizeof T);
    memset(la,0,sizeof la);
    cnt=now=0;
    for (int i=1;i<=n;i++)scanf("%d",&a[i]);
    scanf("%d",&m);
    rt[0]=build(0,n);
    for (int i=1;i<=n;i++)
     {
         if (!la[a[i]])rt[i]=insert(rt[i-1],0,n,0,a[i]);
         else rt[i]=insert(rt[i-1],0,n,la[a[i]],a[i]);
         la[a[i]]=i;
     }
    while (m--)
     {
         scanf("%d%d",&x,&y);
         printf("%lld
",find(rt[y],0,x-1,0,n)-find(rt[x-1],0,x-1,0,n));
     }
    }
    return 0; 
}
原文地址:https://www.cnblogs.com/xuanyiming/p/7921974.html