BZOJ2588 主席樹 樹上差分

2022-05-20 02:30:34 字數 2462 閱讀 8134

這種類似於第k小的題,一般容易想到主席樹,但是樹鏈並不能不是乙個按順序的序列,使用樹鏈剖分也不太容易維護幾條鏈之間的第k小關係。

但是可以從主席樹的字首和思想入手,一般情況的主席樹,查詢的時候是query(r) - query(l - 1)來詢問區間內的數值數量,在這一題裡面,可以考慮到樹上差分,從樹根開始,以每乙個點的父親為字首建立主席樹。

然後查詢的時候轉變為query(u) + query(v) - query(lca(u,v,)) - query(fa(lca(u,v))) 就可以了。

#include #include 

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

using

namespace

std;

#define for(i, x, y) for(int i=x;i<=y;i++)

#define _for(i, x, y) for(int i=x;i>=y;i--)

#define mem(f, x) memset(f,x,sizeof(f))

#define sca(x) scanf("%d", &x)

#define sca2(x,y) scanf("%d%d",&x,&y)

#define sca3(x,y,z) scanf("%d%d%d",&x,&y,&z)

#define scl(x) scanf("%lld",&x);

#define pri(x) printf("%d\n", x)

#define prl(x) printf("%lld\n",x);

#define clr(u) for(int i=0;i<=n;i++)u[i].clear();

#define ll long long

#define ull unsigned long long

#define mp make_pair

#define pii pair#define pil pair#define pll pair#define pb push_back

#define fi first

#define se second typedef vector

vi;int read()

while (c >= '

0'&&c <= '

9')return x*f;}

const

double eps = 1e-9

;const

int maxn = 1e5 + 10

;const

int inf = 0x3f3f3f3f

;const

int mod = 1e9 + 7

; int

n,m,k;

intval[maxn],hash[maxn],tot,cnt,t[maxn];

struct

edgeedge[maxn * 2

];int

head[maxn],tot;

void

init()

void add(int u,int

v)struct

treetree[maxn * 60

];void newnode(int &t)

void build(int &t,int l,int

r)void update(int &t,int pre,int l,int r,int

p)const

int sp = 20

;int

fa[maxn][sp],dep[maxn];

void dfs(int u,int

la)}

int lca(int u,int

v) }

return u == v?u:fa[u][0];}

int query(int u,int v,int f,int ff,int l,int r,int

k)int

main()

sort(hash + 1,hash + 1 +n);

cnt = unique(hash + 1,hash + 1 + n) - hash - 1

; build(t[

0],1

,cnt);

int root = 1; dfs(root,0

);

int ans = 0

;

for(int i = 1; i <= m; i ++)

return0;

}

bzoj 3631 (樹上差分)

給你一棵有n n個結點的樹,現在給你乙個大小為n n的排列,說明你的行走路徑。你每經過樹上的每乙個點,你就需要將這個點的點權加1。問你最後所有點的點權大小。根據題目的意思,很明顯這道題是乙個非常典型的點差分的問題。我們只需要對結點uiu i vi vi 以及lca ui,vi l ca u i v ...

bzoj 4390(樹上差分)

給你一顆有n n個結點的樹以及m m個路徑。對於每乙個路徑pat hipa thi 代表著你將會從uiu i 走到vivi 現在問你,你走完著m m個路徑後,在這n n個結點中經過的最多的次數。首先,如果我們用dfs dfs在樹上暴力去跑的話,顯然時間肯定是接受不了的。因此我們需要考慮一種較為優美的...

BZOJ3631 松鼠的新家 樹上差分 點差分

n n 3e5 個點的一棵樹,給出a1到an,從a1走到a2,再從a2走到a3,從a3走到a4,從an 1走到an 要求,走的路徑上每走乙個點放乙個糖果,最後an不放,問每個點放了多少糖果 裸的樹上點差分,a1走到a2,就把這一條路徑 1即可 由於後續又把a2走到a3的路徑 1,故需要對a2單點減一...