結果

問題 No.3407 Birds-of-Paradise' Christmas Live
コンテスト
ユーザー t98slider
提出日時 2025-12-14 00:35:10
言語 C++17
(gcc 15.2.0 + boost 1.89.0)
結果
WA  
実行時間 -
コード長 2,309 bytes
記録
記録タグの例:
初AC ショートコード 純ショートコード 純主流ショートコード 最速実行時間
コンパイル時間 1,998 ms
コンパイル使用メモリ 207,272 KB
実行使用メモリ 15,144 KB
最終ジャッジ日時 2025-12-14 00:35:16
合計ジャッジ時間 4,561 ms
ジャッジサーバーID
(参考情報)
judge4 / judge5
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample AC * 2
other WA * 20
権限があれば一括ダウンロードができます

ソースコード

diff #
raw source code

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

template<class T> istream& operator >> (istream& is, vector<T>& vec) {
    for(T& x : vec) is >> x;
    return is;
}

template<class T> ostream& operator << (ostream& os, const vector<T>& vec) {
    if(vec.empty()) return os;
    os << vec[0];
    for(auto it = vec.begin(); ++it != vec.end(); ) os << ' ' << *it;
    return os;
}

/*
考察
00ではない区間をいい感じに忘れ去れる問題
01,10の区間で0の方
11の区間ならどちらでも可能
11の区間をどう使うかがミソ
-> 2乗なので隣接のうち大きい方に付ければ良さそう
*/

int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    int n, m;
    cin >> n;
    vector<int> w(n);
    cin >> w >> m;
    vector<int> s(m);
    cin >> s;

    vector<int> ca;
    ca.reserve(n + m);
    w.insert(w.begin(), 0);
    for(int i = 0; i < n; i++)w[i + 1] += w[i];
    ca.insert(ca.end(), w.begin(), w.end());
    s.insert(s.begin(), 0);
    for(int i = 0; i < m; i++) s[i + 1] += s[i];
    ca.insert(ca.end(), s.begin(), s.end());

    sort(ca.begin(), ca.end());
    ca.erase(unique(ca.begin(), ca.end()), ca.end());

    int S = 0;
    vector<pair<int,int>> b;
    for(int i = 0, wi = 0, si = 0; i + 1 < ca.size(); i++){
        int dt = ca[i + 1] - ca[i];
        while(wi <= n && ca[i] == w[wi]){
            wi++;
            S ^= 1;
        }
        while(si <= m && ca[i] == s[si]){
            si++;
            S ^= 2;
        }
        b.emplace_back(dt, S);
    }
    for(int i = 0; i < b.size(); i++){
        if(b[i].second != 3) continue;
        int lcnt = 0, rcnt = 0;
        if(i >= 1 && b[i - 1].second >= 1){
            lcnt = b[i - 1].first + b[i].first;
        }
        if(i + 1 < b.size() && b[i + 1].second >= 1){
            rcnt = b[i + 1].first + b[i].first;
        }
        if(lcnt == 0 && rcnt == 0) continue;
        // 01 11 01 11
        // のときにどっちに付けて良いか分からなくないか...
        b[i].first = 0;
        if(lcnt > rcnt){
            b[i - 1].first = lcnt;
        }else{
            b[i + 1].first = rcnt;
        }
    }
    ll ans = 0;
    for(auto &&[cnt, S] : b){
        if(S == 0) continue;
        ans += cnt * (ll)(cnt);
    }
    cout << ans << '\n';
}
0