結果
| 問題 |
No.2520 L1 Explosion
|
| コンテスト | |
| ユーザー |
nono00
|
| 提出日時 | 2023-10-28 08:59:43 |
| 言語 | C++23 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 105 ms / 2,000 ms |
| コード長 | 5,677 bytes |
| コンパイル時間 | 3,596 ms |
| コンパイル使用メモリ | 268,920 KB |
| 実行使用メモリ | 73,984 KB |
| 最終ジャッジ日時 | 2024-09-25 16:12:00 |
| 合計ジャッジ時間 | 5,777 ms |
|
ジャッジサーバーID (参考情報) |
judge2 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 22 |
ソースコード
#include <bits/stdc++.h>
#include <algorithm>
#include <iterator>
#include <vector>
namespace nono {
template <class T>
class Compressor {
public:
Compressor() = default;
Compressor(const std::vector<T>& data): data_(data) {
std::sort(data_.begin(), data_.end());
data_.erase(std::unique(data_.begin(), data_.end()), data_.end());
}
int compress(const T& value) const {
return std::distance(data_.begin(), std::lower_bound(data_.begin(), data_.end(), value));
}
std::vector<int> compress(const std::vector<T>& vec) const {
std::vector<int> result(vec.size());
for (int i = 0; auto v: vec) {
result[i] = compress(v);
i++;
}
return result;
}
T decompress(int i) const {
return data_[i];
}
int size() const {
return data_.size();
}
private:
std::vector<T> data_;
};
} // namespace nono
#include <iostream>
namespace nono {
namespace internal {
constexpr bool is_prime(unsigned long long n) {
for (unsigned long long i = 2; i * i <= n; i++) {
if (n % i == 0) return false;
}
return true;
}
} // namespace internal
template <unsigned long long MOD = 998244353>
class Modint {
public:
static_assert(internal::is_prime(MOD));
constexpr Modint(unsigned long long value = 0): value_(value % MOD) {}
constexpr Modint pow(long long exp) const {
Modint result(1);
Modint base(*this);
while (exp > 0) {
if (exp & 1) {
result *= base;
}
base *= base;
exp >>= 1;
}
return result;
}
constexpr Modint inv() const {
return pow(MOD - 2);
}
void set(unsigned long long value) {
if (value >= MOD) value %= MOD;
value_ = value;
}
unsigned long long get() const {
return value_;
}
friend constexpr bool operator==(const Modint lhs, const Modint rhs) {
return lhs.value_ == rhs.value_;
}
constexpr Modint& operator+=(const Modint other) {
this->value_ += other.value_;
if (this->value_ >= MOD) this->value_ -= MOD;
return *this;
}
constexpr Modint& operator-=(const Modint other) {
this->value_ += MOD - other.value_;
if (this->value_ >= MOD) this->value_ -= MOD;
return *this;
}
constexpr Modint& operator*=(const Modint other) {
this->value_ *= other.value_;
if (this->value_ >= MOD) this->value_ %= MOD;
return *this;
}
constexpr Modint& operator/=(const Modint other) {
*this *= other.inv();
if (this->value_ >= MOD) this->value_ %= MOD;
return *this;
}
constexpr friend Modint operator+(const Modint lhs, const Modint rhs) {
return Modint(lhs) += rhs;
}
constexpr friend Modint operator-(const Modint lhs, const Modint rhs) {
return Modint(lhs) -= rhs;
}
constexpr friend Modint operator*(const Modint lhs, const Modint rhs) {
return Modint(lhs) *= rhs;
}
constexpr friend Modint operator/(const Modint lhs, const Modint rhs) {
return Modint(lhs) /= rhs;
}
friend std::istream& operator>>(std::istream& stream, Modint& mint) {
unsigned long long value;
stream >> value;
mint.set(value);
return stream;
}
friend std::ostream& operator<<(std::ostream& stream, Modint mint) {
stream << mint.get();
return stream;
}
private:
unsigned long long value_;
};
} // namespace nono
namespace nono {
struct Init {};
void solve([[maybe_unused]] const Init& init) {
using Mint = Modint<998244353>;
using Query = std::tuple<long long, long long, long long, long long>;
int n;
long long m;
std::cin >> n >> m;
std::vector<Query> query;
std::vector<long long> xs, ys;
for (int i = 0; i < n; i++) {
long long x, y, h;
std::cin >> x >> y >> h;
long long center_x = (x + y);
long long center_y = (x - y);
long long d = m - h;
xs.push_back(center_x - d);
xs.push_back(center_x + d);
ys.push_back(center_y - d);
ys.push_back(center_y + d);
query.emplace_back(center_x - d, center_y - d, center_x + d, center_y + d);
}
Compressor comp_x(xs), comp_y(ys);
int h = comp_x.size();
int w = comp_y.size();
std::vector sum(h, std::vector<long long>(w));
for (auto [i0, j0, i1, j1]: query) {
i0 = comp_x.compress(i0);
i1 = comp_x.compress(i1);
j0 = comp_y.compress(j0);
j1 = comp_y.compress(j1);
sum[i0][j0]++;
sum[i1][j1]++;
sum[i0][j1]--;
sum[i1][j0]--;
}
for (int i = 0; i + 1 < h; i++) {
for (int j = 0; j < w; j++) {
sum[i + 1][j] += sum[i][j];
}
}
for (int i = 0; i < h; i++) {
for (int j = 0; j + 1 < w; j++) {
sum[i][j + 1] += sum[i][j];
}
}
std::vector<Mint> answer(n + 1);
for (int i = 0; i + 1 < h; i++) {
for (int j = 0; j + 1 < w; j++) {
long long di = comp_x.decompress(i + 1) - comp_x.decompress(i);
long long dj = comp_y.decompress(j + 1) - comp_y.decompress(j);
answer[sum[i][j]] += di * dj;
}
}
for (int i = 1; i <= n; i++) {
std::cout << (answer[i] / Mint(2)) << std::endl;
}
}
} // namespace nono
int main() {
std::cin.tie(0)->sync_with_stdio(0);
std::cout << std::fixed << std::setprecision(16);
int t = 1;
nono::Init init;
while (t--) nono::solve(init);
}
nono00