結果

問題 No.3220 Forest Creation
ユーザー woshinailong
提出日時 2025-08-01 22:23:09
言語 C++17
(gcc 13.3.0 + boost 1.87.0)
結果
WA  
実行時間 -
コード長 2,189 bytes
コンパイル時間 1,929 ms
コンパイル使用メモリ 200,988 KB
実行使用メモリ 7,716 KB
最終ジャッジ日時 2025-08-01 22:23:13
合計ジャッジ時間 3,203 ms
ジャッジサーバーID
(参考情報)
judge2 / 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 V and sum of degrees sumD
    ll V = 0, sumD = 0;
    for (int i = 0; i <= n; i++) {
        V += a[i];           // include isolated vertices (degree 0)
        sumD += a[i] * i;
    }
    
    // Basic necessary conditions
    if ((sumD & 1) || sumD > 2*(V - 1)) {
        cout << "No\n";
        return 0;
    }
    // Max degree constraint: no degree >= V
    for (int d = V; d <= n; d++) {
        if (a[d] > 0) {
            cout << "No\n";
            return 0;
        }
    }

    // Build degree groups 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 counts and prefix sum of degrees
    vector<ll> pc(m), ps(m);
    for (int i = 0; i < m; i++) {
        pc[i] = cnt[i] + (i > 0 ? pc[i-1] : 0);
        ps[i] = cnt[i]*degs[i] + (i > 0 ? ps[i-1] : 0);
    }
    
    // Check Erdos-Gallai for forest
    for (int i = 0; i < m; i++) {
        ll k = pc[i];         // number of largest-degree vertices
        ll lhs = ps[i];       // sum of their degrees
        // compute rhs = k*(k-1) + sum_{j>i} min(degs[j], k)
        ll rhs = k*(k-1);
        if (i < m-1) {
            // find first index j>i where degs[j] <= k
            int l = i+1, r = m;
            while (l < r) {
                int mid = (l+r)/2;
                if (degs[mid] > k) l = mid+1;
                else r = mid;
            }
            int p = l;
            // those with deg > k contribute k each
            ll cntBig = (p-1 >= i+1 ? pc[p-1] - pc[i] : 0);
            // those with deg <= k contribute deg
            ll sumSmall = ps[m-1] - (p-1 >= 0 ? ps[p-1] : 0);
            rhs += cntBig * k + sumSmall;
        }
        if (lhs > rhs) {
            cout << "No\n";
            return 0;
        }
    }

    cout << "Yes\n";
    return 0;
}
0