洛谷P3384 模板 樹鏈剖分

2022-04-30 23:48:24 字數 2876 閱讀 8869

如題,已知一棵包含\(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\)取模

輸入樣例#1:

5 5 2 24

7 3 7 8 0

1 21 5

3 14 1

3 4 2

3 2 2

4 51 5 1 3

2 1 3

輸出樣例#1:

2

21

時空限制:\(1s\),\(128m\)

資料規模:

對於\(30\%\)的資料: \(n \leq 10, m \leq 10\)

對於\(70\%\)的資料: \(n \leq ^3, m \leq ^3\)

對於\(100\%\)的資料: \(n \leq ^5, m \leq ^5\)

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

樣例說明:

樹的結構如下:

各個操作如下:

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

思路:思路在課件裡面寫過了,不想再寫一遍了……就是乙個樹鏈剖分加線段樹的板子題。

**:

#include#include#include#define maxn 100007 

#define ll long long

#define ls rt<<1

#define rs rt<<1|1

using namespace std;

int mod,head[maxn],d[maxn],sum[maxn<<2],a[maxn];

int num,cnt,n,m,lazy[maxn<<2],fa[maxn],id[maxn];

int rt,w[maxn],top[maxn],size[maxn],son[maxn];

inline int qread()

struct node e[maxn<<1];

inline void ct(int u, int v)

inline void pushup(int rt)

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

int mid=(l+r)>>1;

build(ls,l,mid);

build(rs,mid+1,r);

pushup(rt);

}inline void pushdown(int rt, int len)

}void modify(int rt, int l, int r, int l, int r, int val)

int csum(int rt, int l, int r, int l, int r)

void dfs1(int u, int f)

}}void dfs2(int u, int t)

}int calc(int x, int y)

void cal(int x, int y, int val)

int main()

d[rt]=1,fa[rt]=1;

dfs1(rt,0);dfs2(rt,rt);build(1,1,n);

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

if(k==2)

if(k==3)

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

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

洛谷 P3384 模板 樹鏈剖分

樹鏈剖分詳情 跳轉大佬部落格 解題心得 個人看來其實樹鏈剖分就是把一棵標號沒有實際意義的樹重新標號,標號的規則按照重鏈優先,在有序之後用線段樹之類的資料結構來維護。include using namespace std const int maxn 1e5 100 struct node node ...