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...