樹鏈剖分的一些總結(TO DO)

2021-09-02 17:48:29 字數 1505 閱讀 9806

樹鏈剖分的核心思想就是將乙個樹上問題轉化為鏈上問題,然後就可以用線段樹解決啦。

這裡有乙個重鏈和輕鏈的概念。找到每個節點的重兒子作為他的son存下來。將每個點和他的重兒子們作為一條鏈搞下去。

#include using namespace std;

const int maxn=400005;

int n,m,root,mod;

int tot,cnt;

int u[maxn],v[maxn],head[maxn],nxt[maxn],dep[maxn],size[maxn];

int sum[maxn],add[maxn],son[maxn],fa[maxn],a[maxn],id[maxn];

int top[maxn],wt[maxn];

void add_edge(int x,int y)

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

int mid=(l+r)/2;

build(root*2,l,mid);

build(root*2+1,mid+1,r);

sum[root]=sum[root*2]+sum[root*2+1];

}void push_down(int root,int l,int r)

}void update(int root,int l,int r,int l,int r,int k)

push_down(root,l,r);

int mid=(l+r)/2;

if(mid>=l) update(root*2,l,mid,l,r,k);

if(mid+1<=r) update(root*2+1,mid+1,r,l,r,k);

sum[root]=(sum[root*2]+sum[root*2+1])%mod;

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

push_down(root,l,r);

int mid=(l+r)/2;

if(mid>=l) ans+=query(root*2,l,mid,l,r);

ans%=mod;

if(mid+1<=r) ans+=query(root*2+1,mid+1,r,l,r);

return ans%mod;

}void dfs1(int x,int father,int deep) }}

void dfs2(int x,int topf)

}int qrange(int x,int y)

void uprange(int x,int y,int k)

int main()

dfs1(root,0,1);dfs2(root,root);

build(1,1,n);

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

if(k==2)

if(k==3)

if(k==4)

}return 0;

}

樹鏈剖分總結

樹鏈剖分思想不是很複雜。首先給出幾個定義吧 其核心思想就是,將一棵樹拆成多條鏈,然後對於每一條鏈,就用資料結構去維護。有個不會證明的性質,就是如果將一顆樹拆成多條重鏈和輕邊,那麼重鏈的個數不會超過 log 2n 輕邊的邊數也不會超過 log 2n 因為這個性質,很多操作我們可以很高效地完成。這個之後...

樹鏈剖分總結

把樹剖成鏈再操作 部落格安利 維護7個不同陣列,通常和線段樹一起使用 1 模板題 p3384 模板 樹鏈剖分 p3178 haoi2015 樹上操作 p2590 zjoi2008 樹的統計 p2146 軟體包管理器 p2420 讓我們異或吧 2 應用題 p3950 部落衝突 p3038 牧草種植 1...

模板總結 樹鏈剖分

給定一顆樹,要求對樹上的路徑 u,v 進行高效操作。1 更新路徑 u,v 上所有點的權值,單點查詢樹上某點的權值 2 更新結點u的權值,查詢路徑 u,v 上的權值和 3 更新路徑 u,v 上的權值,查詢路徑 u,v 上的權值和 4 更新結點u的權值,查詢路徑 u,v 上的lcis 5 更新結點u到根...