权值线段树

所谓权值线段树,就是指线段树内存的是权值。好像是废话。给出一些数,要查询一个区间内的数的个数。这时可以用权值线段树,开个n(n为给出的数的最大值)个点的线段树。然后就能轻松的维护了当然树状数组更简单

动态开点

为什么要动态开点呢?当然是因为空间不够啊。比如还是上面那个例子。加入给出的数的最大值为\(10^{12}\),并且无法离散化,显然空间开不下。那么就需要动态开点了。

思想

动态开点的思想就是,初始线段树只有一个根。当插入节点的时候在把那些需要的节点开出来。具体方法其实看一下代码就明白了。

void update(int &rt,int l,int r,int pos,int c) {
   if(!rt) {
      rt = ++num;
      tree[rt] = c;
   }
   tree[rt] = min(tree[rt],c);
   if(l == r) return;
   int mid = (l + r) >> 1;
   if(pos <= mid) update(ls[rt],l,mid,pos,c);
   else update(rs[rt],mid + 1,r,pos,c);
}

这就是插入的代码。注意在rt上面是有"&"的。其他的操作就和普通线段树一样了。

一道例题

hdu6183
题解