HAOI2015 樹上操作題解

2021-08-27 14:05:06 字數 1984 閱讀 7600

有一棵點數為 n 的樹,以點 1 為根,且樹點有邊權。然後有 m 個操作,分為三種:

操作 1 :把某個節點 x 的點權增加 a 。

操作 2 :把某個節點 x 為根的子樹中所有點的點權都增加 a 。

操作 3 :詢問某個節點 x 到根的路徑中所有點的點權和。

輸入輸出格式

輸入格式:

第一行包含兩個整數 n, m 。表示點數和運算元。接下來一行 n 個整數,表示樹中節點的初始權值。接下來 n-1 行每行兩個正整數 from, to , 表示該樹中存在一條邊 (from, to) 。再接下來 m 行,每行分別表示一次操作。其中第乙個數表示該操作的種類( 1-3 ) ,之後接這個操作的引數( x 或者 x a ) 。

輸出格式:

對於每個詢問操作,輸出該詢問的答案。答案之間用換行隔開。

輸入輸出樣例

輸入樣例#1:

5 5

1 2 3 4 5

1 2

1 4

2 3

2 5

3 3

1 2 1

3 5

2 1 2

3 3

輸出樣例#1:

6 9

13好吧,一道裸的樹鏈剖分板子題,嗯,直接上**。

#include

using namespace std;

#define ll long long

const

int maxn=500000+10;

inline ll gi()

#define mid ((l+r)>>1)

#define lson rt<<1,l,mid

#define rson rt<<1|1,mid+1,r

#define len (r-l+1)

ll n,m;

struct edgeh[maxn<<1];

ll head[maxn<<1];

ll tot,to[maxn],w[maxn],wt[maxn];

ll a[maxn<<2],laz[maxn<<2];

ll son[maxn],id[maxn],fa[maxn],cnt,dep[maxn],siz[maxn],top[maxn];

ll res=0;

inline

void add(ll u,ll v)

inline

void pushdown(ll rt,ll lenn)

inline

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

build(lson);

build(rson);

a[rt]=(a[rt<<1]+a[rt<<1|1]);

}inline

void query(ll rt,ll l,ll r,ll l,ll r)

else

}inline

void update(ll rt,ll l,ll r,ll l,ll r,ll k)

else

}inline ll qrange(ll x,ll y)

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

res=0;

query(1,1,n,id[x],id[y]);

ans+=res;

return ans;

}inline

void updson(ll x,ll k)

inline

void dfs1(ll x,ll f,ll deep)

}inline

void dfs2(ll x,ll topf)

}int main()

else

if(k==2)

else

}return

0;}

HAOI2015 樹上操作

題目描述 有一棵點數為 n 的樹,以點 1 為根,且樹點有邊權。然後有 m 個操作,分為三種 操作 1 把某個節點 x 的點權增加 a 操作 2 把某個節點 x 為根的子樹中所有點的點權都增加 a 操作 3 詢問某個節點 x 到根的路徑中所有點的點權和。輸入格式 第一行包含兩個整數 n,m 表示點數...

HAOI2015 樹上操作

有一棵點數為 n 的樹,以點 1 為根,且樹點有邊權。然後有 m 個操作,分為三種 操作 1 把某個節點 x 的點權增加 a 操作 2 把某個節點 x 為根的子樹中所有點的點權都增加 a 操作 3 詢問某個節點 x 到根的路徑中所有點的點權和。輸入格式 第一行包含兩個整數 n,m 表示點數和運算元。...

HAOI2015 樹上操作

嘟嘟嘟 樹剖自然可解,就是一道板子題,而且這道題還只問到根節點的距離是多少,而不是樹上任意兩點距離,就更方便了。1 include2 include3 include4 include5 include6 include7 include8 include9 include10 include11 ...