結果

問題 No.3220 Forest Creation
ユーザー woshinailong
提出日時 2025-08-01 22:22:20
言語 C++17
(gcc 13.3.0 + boost 1.87.0)
結果
WA  
実行時間 -
コード長 2,349 bytes
コンパイル時間 1,830 ms
コンパイル使用メモリ 200,856 KB
実行使用メモリ 7,720 KB
最終ジャッジ日時 2025-08-01 22:22:24
合計ジャッジ時間 3,331 ms
ジャッジサーバーID
(参考情報)
judge5 / judge4
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample AC * 2
other AC * 43 WA * 2
権限があれば一括ダウンロードができます

ソースコード

diff #

#include <bits/stdc++.h>
using namespace std;
using ll = long long;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int N;
    cin >> N;
    vector<ll> A(N+1);
    for (int i = 0; i <= N; i++) {
        cin >> A[i];
    }
    
    // Total vertices and sum of degrees
    ll V = 0, sumD = 0;
    for (int d = 0; d <= N; d++) {
        V += A[d];
        sumD += A[d] * d;
    }
    
    // Basic necessary checks
    if ((sumD & 1) || sumD > 2 * (V - 1)) {
        cout << "No\n";
        return 0;
    }
    // Max degree
    for (int d = V; d <= N; d++) {
        if (A[d] > 0) {
            cout << "No\n";
            return 0;
        }
    }
    
    // Build degree groups (degree value, count) in descending order
    vector<int> degs;
    vector<ll> cnt;
    for (int d = N; d >= 0; d--) {
        if (A[d] > 0) {
            degs.push_back(d);
            cnt.push_back(A[d]);
        }
    }
    int m = degs.size();
    
    // Prefix sums of counts and degree*counts
    vector<ll> pc(m), ps(m);
    for (int i = 0; i < m; i++) {
        pc[i] = cnt[i] + (i ? pc[i-1] : 0);
        ps[i] = cnt[i] * degs[i] + (i ? ps[i-1] : 0);
    }
    
    // Erdős–Gallai check at each prefix boundary
    for (int t = 0; t < m; t++) {
        ll k = pc[t];           // number of vertices in prefix
        ll leftSum = ps[t];     // sum of degrees in prefix
        // Compute right side: k*(k-1) + sum_{rem} min(d_i, k)
        ll rhs = k * (k - 1);
        if (k < 0 || k > V) { // sanity
            cout << "No\n";
            return 0;
        }
        if (t == m-1) {
            // no remaining vertices
        } else {
            // binary search for first index p > t where degs[p] <= k
            int l = t+1, r = m;
            while (l < r) {
                int mid = (l + r) >> 1;
                if (degs[mid] > k) l = mid + 1;
                else r = mid;
            }
            int p = l;
            // big degrees > k in [t+1..p-1]
            ll cntBig = (p-1 >= t+1) ? (pc[p-1] - pc[t]) : 0;
            // small degrees <= k in [p..m-1]
            ll sumSmall = ps[m-1] - (p-1 >= 0 ? ps[p-1] : 0);
            rhs += cntBig * k + sumSmall;
        }
        if (leftSum > rhs) {
            cout << "No\n";
            return 0;
        }
    }
    
    cout << "Yes\n";
    return 0;
}
0