結果

問題 No.1623 三角形の制作
ユーザー cutmdocutmdo
提出日時 2022-09-03 18:30:22
言語 C++17
(gcc 12.3.0 + boost 1.83.0)
結果
AC  
実行時間 468 ms / 2,000 ms
コード長 2,782 bytes
コンパイル時間 821 ms
コンパイル使用メモリ 83,020 KB
実行使用メモリ 286,720 KB
最終ジャッジ日時 2024-04-28 15:53:33
合計ジャッジ時間 11,433 ms
ジャッジサーバーID
(参考情報)
judge1 / judge4
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 325 ms
285,056 KB
testcase_01 AC 319 ms
285,056 KB
testcase_02 AC 405 ms
285,952 KB
testcase_03 AC 403 ms
285,952 KB
testcase_04 AC 397 ms
285,824 KB
testcase_05 AC 468 ms
286,720 KB
testcase_06 AC 352 ms
285,440 KB
testcase_07 AC 407 ms
285,952 KB
testcase_08 AC 356 ms
285,312 KB
testcase_09 AC 397 ms
285,952 KB
testcase_10 AC 448 ms
286,464 KB
testcase_11 AC 407 ms
286,080 KB
testcase_12 AC 373 ms
285,568 KB
testcase_13 AC 376 ms
285,696 KB
testcase_14 AC 381 ms
285,696 KB
testcase_15 AC 453 ms
286,720 KB
testcase_16 AC 448 ms
286,592 KB
testcase_17 AC 450 ms
286,720 KB
testcase_18 AC 468 ms
286,720 KB
testcase_19 AC 384 ms
285,952 KB
testcase_20 AC 331 ms
285,056 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

#include <iostream>
#include <vector>

template<
    class S,   // 要素の型
    S element, // 元
    class T, // 2項演算子
    class U // 逆元
>
struct Group {
    S m_val;
    Group() :m_val(element) {}
    Group(S val) :m_val(val) {}
    Group inverse()const { return U()(m_val); }
    Group binaryOperation(const Group& g)const { return T()(m_val, g.m_val); }
};

template<class P> struct F_A_Inv { auto operator()(P x)const { return -x; } };
template<class P> struct F_A_Bin { auto operator()(P x, P y)const { return x + y; } };
template<class P> using AdditiveGroup = Group<P, P(0), F_A_Bin<P>, F_A_Inv<P>>;

template <class Group = AdditiveGroup<long long>>
class Accumulation2D {
private:
    using S = decltype(Group().m_val);

    const int h;
    const int w;
    std::vector<std::vector<Group>> sumList;
public:

    Accumulation2D() = delete;
    Accumulation2D(const std::vector<std::vector<S>>& v) :
        h(v.size()),
        w(v[0].size()),
        sumList(h + 1, std::vector<Group>(w + 1)) {
        for(int i = 0; i < h; ++i) for(int j = 0; j < w; ++j) {
            sumList[i + 1][j + 1] = v[i][j];
        }
        for(int i = 0; i < h; ++i) for(int j = 0; j < w + 1; ++j) {
            sumList[i + 1][j] = sumList[i + 1][j].binaryOperation(sumList[i][j]);
        }
        for(int i = 0; i < h + 1; ++i) for(int j = 0; j < w; ++j) {
            sumList[i][j + 1] = sumList[i][j + 1].binaryOperation(sumList[i][j]);
        }
    }
    S get(int y, int x) {
        return sumList[y + 1][x + 1].m_val;
    }
    S get(int y1, int x1, int y2, int x2) {
        if(y2 < y1 || x2 < x1) { return Group().m_val; }
        x1 = std::max(x1, 0); y1 = std::max(y1, 0);
        y2 = std::min(y2, h - 1); x2 = std::min(x2, w - 1);
        return sumList[y2 + 1][x2 + 1]
            .binaryOperation(sumList[y1][x1])
            .binaryOperation(sumList[y2 + 1][x1].inverse())
            .binaryOperation(sumList[y1][x2 + 1].inverse()).m_val;
    }
};

using ll = long long;
using std::cout;
using std::cin;
constexpr char endl = '\n';

signed main() {
    int n;
    cin >> n;

    constexpr ll size = 3e3 + 1;

    std::vector<ll> rv; rv.reserve(n);
    for(int _ = 0; _ < n; ++_) { int r; cin >> r; rv.emplace_back(r); }
    std::vector<ll> gc(size), bc(size);
    for(int _ = 0; _ < n; ++_) { int b; cin >> b; ++bc[b]; }
    for(int _ = 0; _ < n; ++_) { int g; cin >> g; ++gc[g]; }

    std::vector<std::vector<ll>> table(size, std::vector<ll>(2 * size));
    for(int i = 0; i < size; ++i)for(int j = 0; j < size; ++j) {
        table[std::max(i, j)][i + j] += gc[i] * bc[j];
    }
    auto acc = Accumulation2D<>(table);

    ll ans = 0;
    for(const auto& r : rv) {
        ans += acc.get(0, r + 1, r, 2 * size - 1);
    }
    cout << ans << endl;
}
0