P3676 小清新資料結構題 (樹鏈剖分)

2021-10-07 22:05:57 字數 3271 閱讀 2267

題目鏈結

題面:

題解:見注釋

**:

#include

#include

#include

#include

#include

#include

#include

#include

#define ll long long

#define llu unsigned ll

#define int ll

using

namespace std;

const ll lnf=

0x3f3f3f3f3f3f3f3f

;const

int maxn=

200100

;int n,q;

int head[maxn]

,ver[maxn<<1]

,nt[maxn<<1]

;int f[maxn]

,d[maxn]

,si[maxn]

,son[maxn]

,rk[maxn]

;int top[maxn]

,id[maxn]

;int s[maxn]

,vi[maxn]

;int tot=

1,cnt=0;

int ans1=0;

void

add(

int x,

int y)

void

dfs1

(int x,

int fa)

ans1+

=s[x]

*s[x];}

void

dfs2

(int x,

int t)

}struct node

t[maxn<<2]

;void

pushup

(int cnt)

void

pushdown

(int cnt)

}void

build

(int l,

int r,

int cnt)

int mid=

(l+r)

>>1;

build

(l,mid,cnt<<1)

;build

(mid+

1,r,cnt<<1|

1);pushup

(cnt);}

void

change

(int l,

int r,ll val,

int cnt)

pushdown

(cnt);if

(l<=t[cnt<<1]

.r)change

(l,r,val,cnt<<1)

;if(r>=t[cnt<<1|

1].l)change

(l,r,val,cnt<<1|

1);pushup

(cnt);}

ll ask

(int l,

int r,

int cnt)

pushdown

(cnt)

; ll ans=0;

if(l<=t[cnt<<1]

.r) ans+

=ask

(l,r,cnt<<1)

;if(r>=t[cnt<<1|

1].l) ans+

=ask

(l,r,cnt<<1|

1);return ans;

}void

changeroad

(int x,

int y,ll val)

if(id[x]

>id[y]

)swap

(x,y)

;change

(id[x]

,id[y]

,val,1)

;}intaskroad

(int x,

int y)

if(id[x]

>id[y]

)swap

(x,y)

; ans=

(ans+

ask(id[x]

,id[y],1

));return ans;

}signed

main

(void

)for

(int i=

1;i<=n;i++

)scanf

("%lld"

,&vi[i]);

dfs1(1

,0);

dfs2(1

,1);

build(1

,cnt,1)

;//這裡的d[x]的編號是從0開始的,即d[1]=0

for(

int i=

1;i<=q;i++

)//考慮換根

//我們假設現在這條路為 1=x1-x2-x3----xk=x

//我們設以1為根x1-xk各點的子樹的權值和為ai

//我們設以x為根x1-xk各點的子樹的權值和為bi

//那麼有ansx=ans1-sumof(ai*ai)+sumof(bi*bi)

//可以得到a[i+1]+b[i]=a[1]=b[k] --->都等於所有的點權和

//可以得到

//ansx=ans1-a1*a1-sum_of_(ai*ai)_from_2_to_k+bk*bk+sum_of((a1-a[i+1])*(a1-a[i+1))_from_1_to_k-1

//ansx=ans1-a1*a1-sum_of_(ai*ai)_from_2_to_k+bk*bk+sum_of((a1-ai)*(a1-ai))_from_2_to_k

//ansx=ans1-sum_of_(ai*ai)_from_2_to_k+sum_of((a1-ai)*(a1-ai))_from_2_to_k

//ansx=ans1+(k-1)*a1*a1-2*a1*sum_of(ai)_from_2_to_k

//ansx=ans1+(k-1)*a1*a1+2*a1*a1-2*a1*sum_of(ai)_from_2_to_k-2*a1*a1

//ansx=ans1+(k+1)*a1*a1-2*a1*sumof(ai)

//其中ai就是si

else}}

return0;

}

P3676 小清新資料結構題

p3676 小清新資料結構題 sum left sum a v right 2 後面那個東西就是子樹內兩兩權值乘積之和。直接維護平方必然不行,都是維護一次然後搞一些操作間接維護的。構造乙個函式 s sum a i c rt sum a u operatorname rt,u sum sum a v ...

Luogu3676 小清新資料結構題

傳送門 維護兩個陣列,乙個是子樹的val和,乙個是子樹的val和的平方和 暴力更新,暴力查詢就可以獲得10分吐槽一波luogu的部分分 include define rg register define il inline define fill a,b memset a,b,sizeof a de...

資料結構 樹鏈剖分

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