模擬7 27 單(liu runda學長的神題)

2022-05-06 22:51:08 字數 2301 閱讀 1765

好像用到一些高中數學知識......

滿分做法:

case 0:已知a陣列求b陣列

因為是樹狀結構,設當前節點x 兒子to

我們從任意一點出發可求出b[root]來,之後我們可以通過尋找兩兩相連節點的關係來o(n)推出全部的b

我們發現x與y之間只有一條邊的貢獻不同,就是他們相連的邊

(邊的貢獻即該邊節點所在子樹通過該點的a權值和)

那麼我們就輕鬆搞掉了......

case 1:已知b求a

設sum[i]為以i為根的子樹的a值和,all為總值。

我們首先可以發現b[x]-b[to]的差值可以用sum[to]表示

兩者之間的差值其實就是all-sum[to]與sum[to]的差值

那麼我們用起高中數學的類似等差數列的東西????

從樹上遍歷一番將所有的邊的x與to的上述式子加和

然後注意記錄每個b陣列的係數,顯然如果是葉子節點為-1,其他也要記錄

我們發現化簡後

ss[1]*b[1]+........=2*(sum[2]+......sum[n])-all*(n-1)

(ss是係數,all是a的總值)

其中(sum[2]......)總值是2*b[1],之後dfs統計就行了

1 #include2 #include3 #include4 #include

5 #include6 #include7 #include8 #include9 #include10

#define ps push_back

11#define maxn 210001

12#define ll long long

13using

namespace

std;

14ll a[maxn],b[maxn];

15ll t,n;

16ll head[maxn],tot;

17struct nodee[2*maxn];

18void

add(ll u,ll v)

1922

bool

vis[maxn];ll sum[maxn];

23ll fa[maxn];ll all;

24void

dfs(ll x)

2538}39

void

dfs_findans(ll x)

4049}50

ll orz;

51void

work_a()

5263 cout<

65ll chu[maxn];

66ll ss[maxn];

67void

dfs_b(ll x)

6880}81

void

dfs_find(ll x)

8292}93

void

work_b()

94109 all=(2*b[1]-pss)/(n-1

);110 sum[1]=all;

111//

printf("all=%lld\n",all);

112 memset(vis,0,sizeof

(vis));

113114 dfs_find(1

);115

116for(ll i=1;i<=n;++i)

117120 cout<

121}

122int

main()

123141 scanf("

%lld

",&orz);

142if(orz==0

)143

148work_a();

149}

150else

151156

work_b();

157}

158}

159 }

view code

模擬單鏈表

package l1 單鏈表 public class link title addnode description todo 新增節點 param param data 引數說明 return void 返回型別 throws public void addnode string data p.n...

模擬單鏈表

1.模擬單鏈表首先要定義節點class node 2.單鏈表的新增 2.1方式一 不按照順序 找到最後乙個節點直接新增 新增節點 public void addnode node node temp temp.next 最後乙個節點的next域指向要新增的節點 temp.next node 2.2方...

單鏈表模擬加法

例如 9 9 9 null 1 null 1 0 0 0 null 思路 使用遞迴,能夠實現從前往後計算。cpp view plain copy print?linktable.cpp 定義控制台應用程式的入口點。include stdafx.h include include using name...