#
include
#include
#include
#include
#include
#include
#include
using
namespace std;
const
int maxn=
1e5+10;
int num[maxn*5]
;//權值線段樹:
//區間的值是這段值域裡的個數的線段樹
//葉子結點的值 是這個數在序列裡出現的次數
//可以當平衡樹用 比平衡樹**好寫
/* 沒有必要build
多組樣例的時候
memset就搞定了
void build(int p,int l,int r)
int mid=(l+r)>>1;
build(p<<1,l,mid);
build(p<<1|1,mid+1,r);
} */
void
update
(int p,
int l,
int r,
int v,
int op)
//op==1或-1,插入或刪除
intkth
(int p,
int l,
int r,
int rank)
//k小值
//求乙個數的最小排名,排名從0起
intrank
(int p,
int l,
int r,
int v)
//[1,v-1]的出現個數 即v-1>mid 即前面3個數v就rank3
intfindpre
(int p,
int l,
int r)
//找前驅 盡可能在小於v的右子樹找
intpre
(int p,
int l,
int r,
int v)
int mid=
(l+r)
>>
1,re;
//如果v在右子樹可能有前驅(至少mid+1比v小)就先查右子樹,l=mid+1
if(mid+
11]&&(re=
pre(p<<1|
1,mid+
1,r,v)))
return re;
//否則查左子樹,r=mid,使r不斷變小直至滿足題意小於v
return
pre(p<<
1,l,mid,v);}
intfindnext
(int p,
int l,
int r)
//找後繼 盡可能在大於v的左子樹找
intnext
(int p,
int l,
int r,
int v)
int mid=
(l+r)
>>
1,re;
//如果左子樹里有比v大的(至少mid比v大)就查左子樹 否則查右子樹
if(v&&(re=
next
(p<<
1,l,mid,v)))
return re;
return
next
(p<<1|
1,mid+
1,r,v);}
intmain()
權值線段樹 模板
ps 維護區間和,時間複雜度 o n logn o nlogn o nlog n include using namespace std typedef long long ll define lson l,m,rt 1 define rson m 1,r,rt 1 1 define pushup ...
權值線段樹
維護全域性的值域資訊,每個節點記錄的是該值域的值出現的總次數。使用二分的思想 離散化的時候,需要用到 支援查詢全域性k小值,全域性rank,前驅,後繼等。單詞操作時間複雜度為o logn 空間複雜度為o n 相對於平衡樹的優勢 簡單,速度快 劣勢 值域較大時,我們需要離散化,變成離線資料結構 我認為...
權值線段樹
include using namespace std int n,m,tre 10003 4 laz 10003 4 void pushdown int num void update int num,int le,int ri,int x,int y,int z pushdown num int...