p3384 樹鏈剖分模板題

2021-09-27 00:22:30 字數 1368 閱讀 8738

樹鏈剖分的**實在是長,少有的幾次**行數過百了

線段樹 在圖論裡面的應用

線段樹是處理區間問題的

在圖論的樹裡面的應用就是通過重鏈的方式dfs編號,形成一段連續的區間,就可以用線段樹來處理了;

能做到的事情為

如題,已知一棵包含n個結點的樹(連通且無環),每個節點上包含乙個數值,需要支援以下操作:

操作1: 格式: 1 x y z 表示將樹從x到y結點最短路徑上所有節點的值都加上z

操作2: 格式: 2 x y 表示求樹從x到y結點最短路徑上所有節點的值之和

操作3: 格式: 3 x z 表示將以x為根節點的子樹內所有節點值都加上z

操作4: 格式: 4 x 表示求以x為根節點的子樹內所有節點值之和

#include #include #include using namespace std;

const int maxn=1e5+7;

struct nodeseg[maxn<<2];

int h[maxn],e[maxn<<1],ne[maxn<<1],idx;

int w[maxn],id[maxn],cnt,w2[maxn],deep[maxn],fa[maxn],siz[maxn],son[maxn],top[maxn];

int n,m,root,mod;

void add(int a,int b)

void dfs1(int x,int f)

}void dfs2(int x,int topf)

}void push_down(int p)

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);

seg[p].sum=(seg[p<<1].sum+seg[p<<1|1].sum)%mod;

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

void change(int p,int l,int r,int d)

push_down(p);

if(l<=mid)change(p<<1,l,r,d);

if(mid+1<=r)change(p<<1|1,l,r,d);

seg[p].sum=(seg[p<<1].sum+seg[p<<1|1].sum)%mod;

}int q_range(int x,int y)

void add_range(int x,int y,int d)

int main()

else if(op==2)else if(op==3)else if(op==4)

}return 0;

}

P3384 模板 樹鏈剖分

傳送門 題目描述 如題,已知一棵包含n個結點的樹 連通且無環 每個節點上包含乙個數值,需要支援以下操作 操作1 格式 1 x y z 表示將樹從x到y結點最短路徑上所有節點的值都加上z 操作2 格式 2 x y 表示求樹從x到y結點最短路徑上所有節點的值之和 操作3 格式 3 x z 表示將以x為根...

P3384 模板 樹鏈剖分

p3384 模板 樹鏈剖分 樹鏈剖分是把一棵樹劃分成幾條鏈,這幾條鏈又能組成陣列,然後把陣列建成線段樹,繼而相當於在樹樹上操作。include include include include include using namespace std const int maxn 2e5 10 int ...

P3384 模板 樹鏈剖分

題目描述 如題,已知一棵包含n個結點的樹 連通且無環 每個節點上包含乙個數值,需要支援以下操作 操作1 格式 1 x y z 表示將樹從x到y結點最短路徑上所有節點的值都加上z 操作2 格式 2 x y 表示求樹從x到y結點最短路徑上所有節點的值之和 操作3 格式 3 x z 表示將以x為根節點的子...