NOMURA プログラミングコンテスト 2020 C - Folia
考察
NOMURA プログラミングコンテスト 2020 C - Folia 解説ACです。
木というだけで何となく苦手な意識をもってしまいがちでしたが、解説を理解しじっくり取り組んでACできました。
ポイントは構築段階の最大ノードのカウントのところ。
先に求めていた各階層の最大ノード数と一つ上の階層から見て考えられる最大ノード数のminをとります。
その際,一つ上の階層から見て考えられる最大ノード数は,二分木の性質から1つ上の階層の1つのノードから高々2つの子しか生えないので,1つ上の階層のノードであって葉でないもの(子をもたないもの)の数,ans[i-1]-A[i-1]の2倍になります。
ans[i]=min((ans[i-1]-A[i-1])*2,maxnode[i]);
ACしたコード
ACしたコードです。
オーバーフローに気づいて禁断の#define int long longを使ってAC。
#include <bits/stdc++.h> using namespace std; #define int long long signed main(){ int N; cin>>N; int A[100000]; //入力 for(int i=0;i<=N;i++){ cin>>A[i]; } //各深さの最低・最高の出力 int maxnode[N+1]; int minnode[N+1]; minnode[N]=A[N]; maxnode[N]=A[N]; for(int i=N;i>0;i--){ //cout<<i<<" "<<minnode[i]<<" "<<maxnode[i]<<endl; minnode[i-1]=(minnode[i]+1)/2+A[i-1]; maxnode[i-1]=maxnode[i]+A[i-1]; } //cout<<0<<" "<<minnode[0]<<" "<<maxnode[0]<<endl; //構成可能かを判定 if(!(minnode[0]<=1 && maxnode[0]>=1)){ cout<<-1<<endl; return 0; } //最大ノードの判定 int ans[N+1]; ans[0]=1; for(int i=1;i<=N;i++){ ans[i]=min((ans[i-1]-A[i-1])*2,maxnode[i]); } int sum=0; for(int i=0;i<=N;i++){ //cout<<i<<" "<<ans[i]<<endl; sum+=ans[i]; } cout<<sum<<endl; return 0; }