P3384 樹鏈剖分,入門,模板)

2021-09-16 18:56:33 字數 1473 閱讀 6266

題目詳見:

如題,已知一棵包含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#include#define n 100009

using namespace std;

struct node

s[2*n];

struct tree

p[3*n];

int w[n],head[n],cnt,fa[n],siz[n],son[n],dep[n],top[n],id[n],wt[n],mod;

void add_edge(int u,int v)

void dfs1(int u,int f,int deep) }}

void dfs2(int u,int t)

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

int mid=(l+r)/2;

build(2*rt,l,mid);

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

p[rt].w=(p[2*rt].w+p[2*rt+1].w)%mod;

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

if(p[rt].c!=0)

int mid=(p[rt].l+p[rt].r)/2;

if(r<=mid)

else

if(l>=mid+1)

else }

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

if(p[rt].c!=0)

int mid=(p[rt].l+p[rt].r)/2;

if(r<=mid)

else

if(l>=mid+1)

else

p[rt].w=(p[2*rt].w+p[2*rt+1].w)%mod;

}int qrange(int u,int v)

void uprange(int u,int v,int k)

void addson(int u,int k)

int qson(int u)

int main()

dfs1(r,-1,1);

cnt=0;

dfs2(r,r);

build(1,1,n);

while(m--)

else

if(tp==2)

else

if(tp==3)

else

}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為根節點的子...