Luo Valley / SPOJ SP3267 solution to a problem

If you want in-depth study of Chairman trees portal .


Description:

A given number of columns \ (\ {A_N \} \) , seeking the closed interval \ ([l, r] \ ) is the number of mutually different.

Method:

Establish sustainable scan sequence of segment tree, if this element is the first time, will correspond to the position of the segment tree plus 1; otherwise, the elements will appear on a corresponding position in the segment tree minus 1, this element corresponds to the position of the segment tree plus one.

For queries \ ([L, r] \) , the first \ (r \) version of the query tree line position \ (L \) , after the interval for the accumulation and click.

Code:

#include<bits/stdc++.h>
#define int long long 
#define Maxn 30010
using namespace std;
inline void read(int &x)
{
    int f=1;x=0;char s=getchar();
    while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
    while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
    x*=f;
}
int n,q;
int a[Maxn]; 
int tot=0;
struct Segtree
{
    int ls,rs,sum;
}tree[Maxn<<5];
int rt[Maxn];
inline void Init(){tot=0;}
inline void pushup(int rt)
{
   tree[rt].sum=tree[tree[rt].ls].sum+tree[tree[rt].rs].sum;
}
inline int build(int l,int r)
{
    int rt=++tot;
    if(l==r) 
    {
        tree[rt].sum=0;
        return rt;
    }
    int mid=(l+r)/2;
    tree[rt].ls=build(l,mid);
    tree[rt].rs=build(mid+1,r);
    pushup(rt);
    return rt;
}
int update(int k,int l,int r,int root,int val)
{
    int rt=++tot;
    tree[rt]=tree[root];
    if(l==k&&r==k)
    {
        tree[rt].sum+=val;
        return rt;
    }
    int mid=(l+r)/2;
    if(k<=mid) tree[rt].ls=update(k,l,mid,tree[rt].ls,val);
    else tree[rt].rs=update(k,mid+1,r,tree[rt].rs,val);
    pushup(rt);
    return rt;
}
int query(int l,int r,int rt,int pos)
{
    if(l==r) return tree[rt].sum;
    int mid=(l+r)/2;
    if(pos<=mid) return tree[tree[rt].rs].sum+query(l,mid,tree[rt].ls,pos);
    else return query(mid+1,r,tree[rt].rs,pos);
}
map<int,int>mp;
signed main()
{
    Init();
    read(n);
    for(int i=1;i<=n;i++)
    {
        read(a[i]);
    }
    rt[0]=build(1,n);
    for(int i=1;i<=n;i++)
    {
        if(mp.find(a[i])==mp.end())
        {
            mp[a[i]]=i;
            rt[i]=update(i,1,n,rt[i-1],1);  
        }else
        {
            int tmprt=update(mp[a[i]],1,n,rt[i-1],-1);
            rt[i]=update(i,1,n,tmprt,1);
        }
        mp[a[i]]=i;
    }
    read(q);
    while(q--)
    {
        int l,r;
        read(l),read(r);
        int ans=query(1,n,rt[r],l);
        printf("%lld\n",ans);
    } 
    return 0;
}

Guess you like

Origin www.cnblogs.com/nth-element/p/11785032.html