LG P3384 模板 樹鏈剖分

2021-08-21 13:10:59 字數 2875 閱讀 4529

p3384 【模板】樹鏈剖分

題目鏈結

題目描述

如題,已知一棵包含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為根節點的子樹內所有節點值之和

輸入格式:

第一行包含4個正整數n、m、r、p,分別表示樹的結點個數、操作個數、根節點序號和取模數(即所有的輸出結果均對此取模)。

接下來一行包含n個非負整數,分別依次表示各個節點上初始的數值。

接下來n-1行每行包含兩個整數x、y,表示點x和點y之間連有一條邊(保證無環且連通)

接下來m行每行包含若干個正整數,每行表示乙個操作,格式如下:

操作1: 1 x y z

操作2: 2 x y

操作3: 3 x z

操作4: 4 x

輸出格式:

輸出包含若干行,分別依次表示每個操作2或操作4所得的結果(對p取模)

輸入樣例:

5 5 2 24

7 3 7 8 0

1 2

1 5

3 1

4 1

3 4 2

3 2 2

4 5

1 5 1 3

2 1 3

輸出樣例:

2 21

說明

時空限制:1s,128m

資料規模:

對於30%的資料: n≤10 ,m≤10

對於70%的資料: n≤10^3 ,m≤10^3

對於100%的資料: n≤10^5 ,m≤10^5

( 其實,純隨機生成的樹lca+暴力是能過的,可是,你覺得可能是純隨機的麼233 )

樣例說明:

樹的結構如下:

各個操作如下:

故輸出應依次為2、21(重要的事情說三遍:記得取模)

題解

樹鏈剖分 .

這題很多人寫了線段樹,其實可以只寫樹狀陣列。

**

#include

#include

#include

#include

#define ll long long

using namespace std;

const

int maxn=1e5+5;

int n,m,r,p,tot,lnk[maxn],nxt[maxn<<1],son[maxn<<1],a[maxn];

ll c1[maxn],c2[maxn];

int dep[maxn],siz[maxn],fa[maxn],hv[maxn];

intid[maxn],top[maxn],cnt;

inline ll rad()

while (isdigit(ch)) ret=ret*10+ch-'0',ch=getchar();

return ret*f;

}inline

void add(int x,int y)

inline

void put_(ll *c,int x,int dat)while(x<=n);}//樹狀陣列的修改

inline ll get_(ll *c,int x)while(x>=1);return sum;}//樹狀陣列的查詢

inline

void putted(int x,int dat)

inline ll getted(int x)

inline

void putlr(int l,int r,int dat)//區間修改

inline ll getlr(int l,int r)//區間查詢

void dfs1(int x,int f)

}void dfs2(int x,int tpf)

inline ll query_link(int x,int y)

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

return (ans+getlr(id[x],id[y]))%p;

}inline ll query_tree(int x)

inline

void change_link(int x,int y,int dat)

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

}inline

void change_tree(int x,int dat)

int main()

dfs1(r,0);dfs2(r,r);

for (int i=1;i<=n;i++) putlr(id[i],id[i],a[i]);

for (int i=1,x,y;i<=m;i++)

}return

0;}

樹鏈剖分 P3384 模板 樹鏈剖分

題目描述 戳這裡 題解 其實樹剖的重點就在於輕重鏈,這篇文章寫的很好 然而我線段樹寫得全是問題,改了半天2333 如下 include include include using namespace std const int maxn 100005 int n,m,root,tt,tot,lnk ...

P3384 模板 輕重鏈剖分(樹鏈剖分模板)

入口 題目描述 如題,已知一棵包含 nn 個結點的樹 連通且無環 每個節點上包含乙個數值,需要支援以下操作 操作 11 格式 1 x y z1 x y z 表示將樹從 xx 到 yy 結點最短路徑上所有節點的值都加上 zz。操作 22 格式 2 x y2 x y 表示求樹從 xx 到 yy 結點最短...

P3384 模板 樹鏈剖分

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