P3384 模板 樹鏈剖分

2021-08-21 10:57:21 字數 1675 閱讀 6050

p3384 【模板】樹鏈剖分

樹鏈剖分是把一棵樹劃分成幾條鏈,這幾條鏈又能組成陣列,然後把陣列建成線段樹,繼而相當於在樹樹上操作。

#include

#include

#include

#include

#include

using namespace std;

const int maxn=2e5+10;

int a[maxn];

int fa[maxn],dep[maxn],num[maxn],son[maxn];

int top[maxn],p[maxn],fp[maxn];

int cnt,tot;

int n,m,r,mod;

struct node

edge[maxn];

int head[maxn];

void add(int u,int to)

struct node

tree[maxn*20];

void init()

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

int mid=(l+r)/2;

build(i<<1,l,mid);

build(i<<1|1,mid+1,r);

tree[i].val=(tree[i<<1].val+tree[i<<1|1].val)%mod;

}void pushdown(int i)

}int query(int i,int ql,int qr)

void update(int i,int ql,int qr,int k)

pushdown(i);

if(ql<=mid) update(i<<1,ql,qr,k);

if(qr>mid) update(i<<1|1,ql,qr,k);

tree[i].val=(tree[i<<1].val+tree[i<<1|1].val)%mod;

}void dfs1(int u,int pre,int d)

}}void getpos(int u,int sp)

}void solve1(int

x,int

y,int z)

if(dep[x]>dep[y]) swap(x,y);

update(1,p[x],p[y],z);

}int solve2(int

x,int

y) if(dep[x]>dep[y]) swap(x,y);

ans+=query(1,p[x],p[y])%mod;

return ans%mod;

}void solve3(int

x,int z)

int solve4(int

x)int main()

for(int i=1;iint u,v;

scanf("%d

%d",&u,&v);

add(u,v);

add(v,u);

}dfs1(r,0,1);

getpos(r,r);

build(1,1,n);

for(int i=0;ielse

if(q==2)

else

if(q==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 模板 樹鏈剖分

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

P3384 模板 樹鏈剖分

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