牛客練習賽78 補題

2021-10-22 03:47:10 字數 1860 閱讀 6379

b:cca的搬運

注意陣列的頭和尾在實際模擬時的情形

#include

using

namespace std;

const

int maxn=

1e5+5;

int a[maxn]

,dp[maxn]

,n,m,x1,up[maxn]

,ans,sum,vis[maxn]

,d,b[maxn]

,k,t;

intmain()

for(

int i=

1;i<=k;i++

)else

t+=a[dp[j]];

}for

(int j=s;j) dp[d]

=x; ans+

=t; up[x]=0

;}}printf

("%d\n"

,ans);}

//29

c: cca的子樹

題意:

要選出兩個節點,滿足任意乙個不是另乙個的祖先節點,最大化以兩個節點為根的子樹的點權和 。

如果選不出兩棵合法的子樹,則輸出「error」。

思路:

從根節點1出發,我們可以找到左邊子樹的最大值與右邊子樹的最大值,二者一定可以保證不存在公共的祖先,並且滿足了找左右最大值的要求,我們如果找到了這樣的兩棵子樹那麼就把他們更新一下答案。

並且在左右子樹中也同樣是這樣的問題,我們依次往下即可求解正確的答案。

現在僅僅是把樹形結構從二叉樹變化成了多叉樹,那麼同樣的道理就是在多個兒子中間找到最大的兩個兒子,如果只有乙個兒子就不能更新答案。並且返回包含節點在內的最大子樹點。

這裡判斷只有單鏈一種情況,如果你把答案初始化到代表無窮小的話,可能會出現這樣的資料把你卡掉,這道題目並沒有考慮到。

#include

using

namespace std;

typedef

long

long ll;

ll inf=

-1e10

;const

int maxn=

5e6+5;

ll a[maxn]

,n,vis[maxn]

,ans=inf,to[maxn]

,head[maxn]

,nex[maxn]

,k;void

add(

int x,

int y)

intdfs

(int u,

int f)

if(max2!=0)

//包含max1!=0,更新ans

ans=

max(ans,a[max1]

+a[max2]);

//更新ans,最大子樹權值+次大子樹權值

if(max1==

0||a[u]

>a[max1]

)max1=u;

// 當前樹子樹更新完畢後,繼續向上傳遞,

//當前根節點變成子節點,可以被選用

return max1;

}int

main()

int x,y;

for(

int i=

1;i)dfs(1

,0);

if(ans!=inf)

printf

("%lld\n"

,ans)

;else

printf

("error\n");

}

牛客練習賽60補題

思路 考慮位運算 的特性 只有兩者都為1才會對答案有貢獻 且 對答案貢獻的值為 1 k 其中k是當前1所在二進位制下的位數 所以考慮預處理每乙個位的1出現的次數 其中對每一位都會遍歷n n次 所以每一位對答案的貢獻就是 a i a i 1 i a i 為當前位置1的個數 include using ...

牛客練習賽78小結

前言 質量還可以 d.容斥 二項式反演 題目大意 給你n nn個小球,每個小球有乙個顏色a ia i ai 保證一種顏色最多出現兩次。問你多少種排列方式使得相鄰兩項之間顏色不同.n 1 e5 n leq 1e5 n 1e5 題目思路 發現顏色最多出現兩次.我們可以容斥。將恰好轉至少.令f i f i...

牛客練習賽67 補題 題解

a.牛牛愛字串 題意 給定字串,輸出當中的數字,注意不能有前導零。簡單模擬題,但格式要求非常嚴格,最後乙個數字後不能有空格。還有乙個坑點,如果只有0也是要輸出乙個0的。我是用佇列模擬,去掉前導零。include using namespace std const int n 1e5 10 strin...