結果
| 問題 |
No.1623 三角形の制作
|
| コンテスト | |
| ユーザー |
cutmdo
|
| 提出日時 | 2022-09-03 18:30:22 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 598 ms / 2,000 ms |
| コード長 | 2,782 bytes |
| コンパイル時間 | 1,265 ms |
| コンパイル使用メモリ | 81,648 KB |
| 最終ジャッジ日時 | 2025-02-07 02:27:31 |
|
ジャッジサーバーID (参考情報) |
judge4 / judge4 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 2 |
| other | AC * 19 |
ソースコード
#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;
}
cutmdo