• 在线主席树不同数


     1 map<int,int>mp;//在线主席树 
     2 int a[N],tot,n,q;
     3 int T[M],lson[M],rson[M],val[M];
     4 int bulid(int l,int r){
     5     int root=tot++;
     6     val[root]=0;
     7     int m=(l+r)>>1;
     8     if(l!=r){
     9         lson[root]=bulid(l,m);
    10         rson[root]=bulid(m+1,r);
    11     }
    12     return root;
    13 }
    14 int update(int root,int pos,int v){
    15     int newroot=tot++,tmp=newroot;
    16     int l=1,r=n;
    17     val[newroot]=val[root]+v;
    18     while(l<r){
    19         int m=(l+r)>>1;
    20         //更新的时候需要充分利用历史信息
    21         //更新原来的左子树,右子树不变
    22         if(pos<=m){
    23             lson[newroot]=tot++;rson[newroot]=rson[root];
    24             newroot=lson[newroot];root=lson[root];
    25             r=m;
    26         }
    27         //更新右子树
    28         else{
    29             rson[newroot]=tot++;lson[newroot]=lson[root];
    30             newroot=rson[newroot];root=rson[root];
    31             l=m+1;
    32         }
    33         val[newroot]=val[root]+v;
    34     }
    35     return tmp;
    36 }
    37 int query(int root,int pos){
    38     int ret=0;
    39     int l=1,r=n;
    40     while(pos<r){
    41         int m=(l+r)>>1;
    42         if(pos<=m){
    43             r=m;
    44             root=lson[root];
    45         }
    46         else{
    47             ret+=val[lson[root]];
    48             root=rson[root];
    49             l=m+1;
    50         }
    51     }
    52     return ret+val[root];
    53 }
    54 int main(){
    55     while(scanf("%d",&n)!=EOF){
    56         tot=0;   //结点数
    57         for(int i=1;i<=n;i++)
    58             scanf("%d",&a[i]);
    59         T[n+1]=bulid(1,n);
    60         for(int i=n;i;i--){
    61             int nxt;
    62             map<int,int>::iterator it=mp.find(a[i]);
    63             if(it==mp.end()) nxt=n+1;
    64             else nxt=it->second;
    65             //如果这是第一次出现,也就是最后一个位置上,则直接更新
    66             if(nxt>n)
    67                 T[i]=update(T[i+1],i,1);
    68             //在原来的位置上擦掉,在当前位置更新
    69             else{
    70                 int t=update(T[i+1],nxt,-1);
    71                 T[i]=update(t,i,1);
    72             }
    73             mp[a[i]]=i;
    74         }
    75         scanf("%d",&q);
    76         while(q--){
    77             int l,r;
    78             scanf("%d%d",&l,&r);
    79             printf("%d
    ",query(T[l],r));
    80         }
    81     }
    82     return 0;
    83 }
  • 相关阅读:
    oracle 动态SQL
    Oracle 学习PL/SQL
    SQL优化原理
    JAVA环境配置
    Java接口
    Java数据类型、操作符、表达式
    C#-VS配置开发环境-摘
    Java版本
    网站构建
    Java 时间、字符串
  • 原文地址:https://www.cnblogs.com/chxer/p/4401112.html
Copyright © 2020-2023  润新知