結果

問題 No.1008 Bench Craftsman
ユーザー nanaenanae
提出日時 2020-03-06 23:28:11
言語 D
(dmd 2.107.1)
結果
WA  
実行時間 -
コード長 5,266 bytes
コンパイル時間 740 ms
コンパイル使用メモリ 106,464 KB
実行使用メモリ 24,960 KB
最終ジャッジ日時 2023-09-04 06:18:01
合計ジャッジ時間 6,439 ms
ジャッジサーバーID
(参考情報)
judge14 / judge12
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 2 ms
4,380 KB
testcase_01 AC 1 ms
4,376 KB
testcase_02 AC 1 ms
4,380 KB
testcase_03 WA -
testcase_04 WA -
testcase_05 WA -
testcase_06 WA -
testcase_07 AC 2 ms
4,376 KB
testcase_08 AC 16 ms
4,376 KB
testcase_09 WA -
testcase_10 WA -
testcase_11 WA -
testcase_12 WA -
testcase_13 WA -
testcase_14 WA -
testcase_15 AC 78 ms
8,828 KB
testcase_16 WA -
testcase_17 AC 77 ms
8,840 KB
testcase_18 WA -
testcase_19 WA -
testcase_20 WA -
testcase_21 WA -
testcase_22 WA -
testcase_23 WA -
testcase_24 WA -
testcase_25 WA -
testcase_26 WA -
testcase_27 WA -
testcase_28 WA -
testcase_29 WA -
権限があれば一括ダウンロードができます

ソースコード

diff #

import std.stdio, std.string, std.conv, std.range;
import std.algorithm, std.array, std.typecons, std.container;
import std.math, std.numeric, std.random, core.bitop;

enum inf = 1_001_001_001;
enum infl = 1_001_001_001_001_001_001L;

enum mod = 1_000_000_007L;

struct Mint {
    long x;

    this(long a) {
        x = a % mod;
        if (x < 0) x += mod;
    }

    this(Mint a) {
        x = a.x;
    }

    ref Mint opAssign(long a) {
        this = Mint(a);
        return this;
    }

    ref Mint opOpAssign(string op)(Mint rhs) {
        static if (op == "+") {
            x += rhs.x;
            if (x >= mod) x -= mod;
        }
        static if (op == "-") {
            x -= rhs.x;
            if (x < 0) x += mod;
        }
        static if (op == "*") {
            (x *= rhs.x) %= mod;
        }
        static if (op == "/") {
            this *= rhs.inv();
        }
        return this;
    }

    ref Mint opOpAssign(string op)(long rhs) {
        static if (op == "^^") {
            this = powmod(this, rhs);
            return this;
        }
        else {
            return mixin("this " ~ op ~ "= Mint(rhs)");
        }
    }

    const Mint powmod(Mint a, long b) {
        Mint res = 1, p = a;
        while (b > 0) {
            if (b & 1) res *= p;
            p *= p;
            b /= 2;
        }
        return res;
    }

    const Mint inv() {
        return powmod(this, mod - 2);
    }

    Mint opUnary(string op)() if (s == "-") {
        return Mint(-x);
    }

    Mint opBinary(string op, T)(const T rhs) {
        return mixin("Mint(this) " ~ op ~ "= rhs");
    }

    Mint opBinaryRight(string op)(const long rhs) {
        return mixin("Mint(rhs) " ~ op ~ "= this");
    }

    bool opEquals(Mint a, Mint b) {
        return a.x == b.x;
    }

    bool opEquals(long rhs) {
        long y = rhs % mod;
        if (y < 0) y += mod;
        return x == y;
    }

    string toString() {
        import std.conv : to;
        return x.to!string;
    }
}

unittest {
    long powmod(long a, long b) {
        return b > 0 ? powmod(a, b / 2)^^2 % mod * a^^(b & 1) % mod : 1L;
    }
    auto a = Mint(2), b = Mint(3);
    assert(a + b == 5);
    assert(a + 5 == 7);
    assert(1 + b == 4);
    assert(a - b == mod - 1);
    assert(a * b == 6);
    assert(a / b == 2 * powmod(3, mod - 2));
    assert(a^^10 == 1024);

    Mint z;
    assert(z == 0);

    (z += 2) *= 3;
    assert(z == 6);
}


void main() {
    int N, M;
    scan(N, M);
    auto a = readln.split.to!(long[]);
    auto x = new int[](M);
    auto w = new long[](M);
    foreach (i ; 0 .. M) {
        scan(x[i], w[i]);
    }
    x[] -= 1;

    auto ws = new long[](N);
    foreach (i ; 0 .. M) {
        ws[x[i]] += w[i];
    }

    foreach (i ; 0 .. N) {
        if (a[i] <= ws[i]) {
            writeln(-1);
            return;
        }
    }

    bool check(long c) {
        if (c == 0) {
            long wss;
            foreach (i ; 0 .. M) {
                wss += w[i];
            }
            return wss < a.reduce!min;
        }
        auto imsl = new long[](N + 1);
        auto imsr = new long[](N + 1);
        auto tei = new long[](N + 1);

        foreach (j ; 0 .. M) {
            auto d = w[j] / c;

            auto r = min(x[j] + d + 1, N).to!int;
            if (x[j] + 1 < r) {
                imsl[x[j] + 1] += -c;
                imsl[r] += c * (r - x[j] - 1);
            }

            auto l = max(0, x[j] - d).to!int;
            if (x[j] - 1 >= l) {
                if (l - 1 >= 0) imsr[l] += c * (x[j] - l);
                imsr[x[j] - 1] += -c;
            }

            tei[l] += w[j];
            tei[r] += -w[j];
        }

        foreach (i ; 1 .. N + 1) {
            imsl[i] += imsl[i - 1];
            tei[i] += tei[i - 1];
        }
        foreach (i ; 1 .. N + 1) {
            imsl[i] += imsl[i - 1];
        }
        foreach_reverse (i ; 0 .. N) {
            imsr[i] += imsr[i + 1];
        }
        foreach_reverse (i ; 0 .. N) {
            imsr[i] += imsr[i + 1];
        }

        auto tot = new long[](N + 1);
        foreach (i ; 0 .. N) {
            tot[i] = imsl[i] + imsr[i] + tei[i];
            if (tot[i] >= a[i]) {
                return false;
            }
        }

        return true;
    }

    long ng = -1, ok = inf;
    while (abs(ok - ng) > 1) {
        auto mid = (ng + ok) / 2;
        (check(mid) ? ok : ng) = mid;
    }

    writeln(ok);
}






void scan(T...)(ref T args) {
    auto line = readln.split;
    foreach (ref arg; args) {
        arg = line.front.to!(typeof(arg));
        line.popFront;
    }
    assert(line.empty);
}

void fillAll(R, T)(ref R arr, T value) {
    static if (is(typeof(arr[] = value))) {
        arr[] = value;
    }
    else {
        foreach (ref e; arr) {
            fillAll(e, value);
        }
    }
}

bool chmin(T, U...)(ref T x, U args) {
    bool isChanged;
    foreach (arg; args) if (x > arg) {
        x = arg;
        isChanged = true;
    }
    return isChanged;
}

bool chmax(T, U...)(ref T x, U args) {
    bool isChanged;
    foreach (arg; args) if (x < arg) {
        x = arg;
        isChanged = true;
    }
    return isChanged;
}

void yes(bool ok, string y = "Yes", string n = "No") {
    return writeln(ok ? y : n);
}
0