zoukankan      html  css  js  c++  java
  • 在线主席树不同数

     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 }
  • 相关阅读:
    【Lua】LuaForWindows_v5.1.4-46安装失败解决方案
    【C++】指针引发的bug
    【C++】指针引发的bug
    【C++】位操作(3)-获取某位的值
    bzoj1444
    bzoj1758
    bzoj3091
    poj1741 bzoj2152
    bzoj2125 3047
    bzoj3669
  • 原文地址:https://www.cnblogs.com/chxer/p/4401112.html
Copyright © 2011-2022 走看看