資料結構 樹鏈剖分

2021-08-18 18:30:40 字數 2470 閱讀 3605

題目描述

如題,已知一棵包含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 2

1 5

3 1

4 1

3 4 2

3 2 2

4 5

1 5 1 3

2 1 3

輸出樣例#1:

2 21

說明時空限制:1s,128m

資料規模:

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

對於70%的資料: n≤1000,m≤1000

對於100%的資料:n≤100000,m≤100000

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

樣例說明:

樹的結構如下:

各個操作如下:

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

題解這個大佬的部落格寫的賊好,羞愧的蒟蒻我都不想寫部落格了。

**

#include

#define ls tree[v<<1]

#define rs tree[v<<1|1]

using

namespace

std;

const

int m=2e5+5;

struct node;

int n,m,root,mod,tot,dad[m],son[m],deep[m],size[m],top[m],val[m],val2[m],id[m];

vector

ed[m];

node tree[m<<2];

void in()

int dfs1(int v,int f,int d)

return size[v];

}void dfs2(int v,int topf)

}void up(int v)

void build(int v,int le,int ri)

int mid=(le+ri)>>1;

build(v<<1,le,mid);

build(v<<1|1,mid+1,ri);

up(v);

}void push(int v,int le,int ri)

void add(int v,int le,int ri,int lb,int rb,int ad)

push(v,le,ri);

int mid=(le+ri)>>1;

if(lb<=mid)add(v<<1,le,mid,lb,rb,ad);

if(mid1|1,mid+1,ri,lb,rb,ad);

up(v);

}int que(int v,int le,int ri,int lb,int rb)

void treeadd(int a,int b,int ad)

if(deep[a]>deep[b])swap(a,b);

add(1,1,n,id[a],id[b],ad);

}int treeque(int a,int b)

if(deep[a]>deep[b])swap(a,b);

ans+=que(1,1,n,id[a],id[b]);

return ans%mod;

}void ac()

case(2):

case(3):

case(4):}}

}int main()

樹鏈剖分 樹鏈剖分講解

好了,這樣我們就成功解決了對樹上修改查詢邊權或點的問題。下面放上 vector v maxn int size maxn dep maxn val maxn id maxn hson maxn top maxn fa maxn 定義 int edge 1,num 1 struct tree e ma...

演算法入門 樹鏈剖分 輕重鏈剖分

目錄 3.0 求 lca 4.0 利用資料結構維護資訊 5.0 例題 參考資料 資料結構入門 線段樹 發表於 2019 11 28 20 39 dfkuaid 摘要 線段樹的基本 建樹 區間查詢 單點修改 及高階操作 區間修改 單點查詢 區間修改 區間查詢 標記下傳 標記永久化 閱讀全文 樹鏈剖分用...

樹鏈剖分 樹剖換根

這是一道模板題。給定一棵 n 個節點的樹,初始時該樹的根為 1 號節點,每個節點有乙個給定的權值。下面依次進行 m 個操作,操作分為如下五種型別 換根 將乙個指定的節點設定為樹的新根。修改路徑權值 給定兩個節點,將這兩個節點間路徑上的所有節點權值 含這兩個節點 增加乙個給定的值。修改子樹權值 給定乙...