權值線段樹 模板

2021-09-20 07:33:28 字數 1716 閱讀 8679

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(rt) t[rt] = t[rt<<1] + t[rt<<1|1];

const int maxn = 1e5 + 10;

int n, t[maxn], a[maxn];

void build(int l, int r, int rt)

void update(int c, int l, int r, int rt)

int m = (l+r)>>1;

if(c<=m) update(c, lson);

else update(c, rson);

pushup(rt);

}int query(int l, int r, int l, int r, int rt)

int main()

printf("%d\n", sum);

}}

用 vec

to

rvector

vector

來存,二分出第 k

kk 大的值,在 vec

to

rvector

vector

中二分找不超過 c

cc 的值

時間複雜度:o(n

log3

n)

o(nlog^3n)

o(nlog

3n)

#include #include #include #include using namespace std;

typedef long long ll;

#define lson l,m,rt<<1

#define rson m+1,r,rt<<1|1

#define pushup(rt) t[rt] = t[rt<<1] + t[rt<<1|1];

const int maxn = 1e5 + 10;

int n, m, a[maxn];

vector t[maxn<<2];

void build(int l, int r, int rt)

int m = (l+r)>>1;

build(lson);

build(rson);

//t[rt].resize(t[rt<<1].size()+t[rt<<1|1].size());

t[rt].resize(r-l+1);

//利用stl的merge函式吧兩個兒子的數列合併

merge(t[rt<<1].begin(),t[rt<<1].end(),\

t[rt<<1|1].begin(),t[rt<<1|1].end(),t[rt].begin());

}// 計算 l到 r 之間, 不超過 c的個數

int query(int l, int r, int c, int l, int r, int rt)

int solve(int l, int r, int k)

return a[l];

}int main()

}}

權值線段樹的模板

include include include include include include include using namespace std const int maxn 1e5 10 int num maxn 5 權值線段樹 區間的值是這段值域裡的個數的線段樹 葉子結點的值 是這個數在序...

權值線段樹

維護全域性的值域資訊,每個節點記錄的是該值域的值出現的總次數。使用二分的思想 離散化的時候,需要用到 支援查詢全域性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...