結果

問題 No.1437 01 Sort
ユーザー novaandcabralnovaandcabral
提出日時 2024-04-22 14:49:02
言語 C++14
(gcc 12.3.0 + boost 1.83.0)
結果
AC  
実行時間 312 ms / 2,000 ms
コード長 2,914 bytes
コンパイル時間 1,050 ms
コンパイル使用メモリ 83,324 KB
実行使用メモリ 5,820 KB
最終ジャッジ日時 2024-04-22 14:49:08
合計ジャッジ時間 5,213 ms
ジャッジサーバーID
(参考情報)
judge3 / judge1
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 2 ms
5,248 KB
testcase_01 AC 2 ms
5,376 KB
testcase_02 AC 2 ms
5,376 KB
testcase_03 AC 2 ms
5,376 KB
testcase_04 AC 2 ms
5,376 KB
testcase_05 AC 2 ms
5,376 KB
testcase_06 AC 1 ms
5,376 KB
testcase_07 AC 2 ms
5,376 KB
testcase_08 AC 2 ms
5,376 KB
testcase_09 AC 1 ms
5,376 KB
testcase_10 AC 1 ms
5,376 KB
testcase_11 AC 1 ms
5,376 KB
testcase_12 AC 2 ms
5,376 KB
testcase_13 AC 312 ms
5,692 KB
testcase_14 AC 286 ms
5,692 KB
testcase_15 AC 58 ms
5,376 KB
testcase_16 AC 232 ms
5,376 KB
testcase_17 AC 135 ms
5,376 KB
testcase_18 AC 235 ms
5,376 KB
testcase_19 AC 189 ms
5,376 KB
testcase_20 AC 144 ms
5,376 KB
testcase_21 AC 270 ms
5,568 KB
testcase_22 AC 286 ms
5,564 KB
testcase_23 AC 274 ms
5,568 KB
testcase_24 AC 281 ms
5,564 KB
testcase_25 AC 295 ms
5,684 KB
testcase_26 AC 245 ms
5,820 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

using ll = long long;
using pll = pair<ll, ll>;

vector<pll> dxy4 = {{-1, 0}, {0, -1}, {0, 1}, {1, 0}};
vector<pll> dxy8 = {{-1, -1}, {-1, 0}, {-1, 1}, {0, -1}, {0, 1}, {1, -1}, {1, 0}, {1, 1}};

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

    ll n, ans =1e18;
    string s;
    cin >> n >> s;

    ll zero = 0, one = 0;
    vector<ll> bit;
    for (ll i = 0; i < n; i++) {
        if (s[i] == '0')
            zero++;
        else {
            one++;
            bit.push_back(i);
            bit.push_back(i + n);
            bit.push_back(i + n + n);
        }
    }
    sort(bit.begin(), bit.end());

    if (zero == n || zero == 0) {
        cout << 0 << endl;
        return 0;
    }

    vector<bool> out(n, true);
    if (s[0] == '1') {
        out[0] = false;
        for (ll i = n - 1; i >= 0; i--) {
            if (s[i] == '1')
                out[i] = false;
            else
                break;
        }
    }

    auto f = [&](ll l1, ll l2) {
        ll sp_l = (l1 + one) % n, sp_r = n;
        if (sp_l == 0) sp_l = n;

        ll ansl = 0, ansr = 0;

        if (bit[l2] <= l1 + n) {
            if (sp_l <= (bit[l2] + n - 1) % n + 1 && (bit[l2] + n - 1) % n + 1 <= sp_r && out[bit[l2] % n])
                ansl = l1 + n - bit[l2] - 1;
            else
                ansl = l1 + n - bit[l2];
        }

        if (l1 + n + one - 1 < bit[l2 + one - 1]) {

            ll ng = -1, ok = one;
            while (ng + 1 != ok) {
                ll mid = (ng + ok) / 2;
                if (l1 + n + mid < bit[l2 + mid])
                    ok = mid;
                else
                    ng = mid;
            }

            bool flag1 = true, flag2 = false;
            ll x = l1 + n + ok;
            if (x % n) x += n - (x % n);
            if (x <= l1 + n + one - 1) {
                if (l1 + n + ok <= bit[l2 + ok] && bit[l2 + ok] <= x) flag2 = true;
                x += n;
            }
            if (l1 + n + ok <= bit[l2 + ok] && bit[l2 + ok] <= x) flag1 = false;
            ansr = one - ok;
            ansr += flag1;
            ansr -= flag2;
        }

        return max(ansl, ansr);
    };

    for (ll l1 = 0; l1 < n; l1++) {
        ll anss = (n + n - l1 - one) % n, sp_l = (l1 + one) % n, sp_r = n;
        if (sp_l == 0) sp_l = n;

        ll ng = -1, ok = n;
        while (ng + 1 != ok) {
            ll mid = (ng + ok) / 2;

            ll x = l1 + n - mid - 1;
            if (!(sp_l <= (x + n - 1) % n + 1 && (x + n - 1) % n + 1 <= sp_r && out[x % n])) x++;
            ll l2 = lower_bound(bit.begin(), bit.end(), x) - bit.begin();

            if (f(l1, l2) <= mid)
                ok = mid;
            else
                ng = mid;
        }

        ans = min(ans, anss + ok * n);
    }
    cout << ans << endl;

    return 0;
}
0