QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#66126 | #4887. Fast Bridges | japan022022 | TL | 580ms | 5540kb | C++20 | 23.0kb | 2022-12-06 23:53:02 | 2022-12-06 23:53:04 |
Judging History
answer
#line 1 "library/my_template.hpp"
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pi = pair<ll, ll>;
using vi = vector<ll>;
using u32 = unsigned int;
using u64 = unsigned long long;
using i128 = __int128;
template <class T>
using vc = vector<T>;
template <class T>
using vvc = vector<vc<T>>;
template <class T>
using vvvc = vector<vvc<T>>;
template <class T>
using vvvvc = vector<vvvc<T>>;
template <class T>
using vvvvvc = vector<vvvvc<T>>;
template <class T>
using pq = priority_queue<T>;
template <class T>
using pqg = priority_queue<T, vector<T>, greater<T>>;
#define vec(type, name, ...) vector<type> name(__VA_ARGS__)
#define vv(type, name, h, ...) \
vector<vector<type>> name(h, vector<type>(__VA_ARGS__))
#define vvv(type, name, h, w, ...) \
vector<vector<vector<type>>> name( \
h, vector<vector<type>>(w, vector<type>(__VA_ARGS__)))
#define vvvv(type, name, a, b, c, ...) \
vector<vector<vector<vector<type>>>> name( \
a, vector<vector<vector<type>>>( \
b, vector<vector<type>>(c, vector<type>(__VA_ARGS__))))
// https://trap.jp/post/1224/
#define FOR1(a) for (ll _ = 0; _ < ll(a); ++_)
#define FOR2(i, a) for (ll i = 0; i < ll(a); ++i)
#define FOR3(i, a, b) for (ll i = a; i < ll(b); ++i)
#define FOR4(i, a, b, c) for (ll i = a; i < ll(b); i += (c))
#define FOR1_R(a) for (ll i = (a)-1; i >= ll(0); --i)
#define FOR2_R(i, a) for (ll i = (a)-1; i >= ll(0); --i)
#define FOR3_R(i, a, b) for (ll i = (b)-1; i >= ll(a); --i)
#define FOR4_R(i, a, b, c) for (ll i = (b)-1; i >= ll(a); i -= (c))
#define overload4(a, b, c, d, e, ...) e
#define FOR(...) overload4(__VA_ARGS__, FOR4, FOR3, FOR2, FOR1)(__VA_ARGS__)
#define FOR_R(...) \
overload4(__VA_ARGS__, FOR4_R, FOR3_R, FOR2_R, FOR1_R)(__VA_ARGS__)
#define FOR_subset(t, s) for (ll t = s; t >= 0; t = (t == 0 ? -1 : (t - 1) & s))
#define all(x) x.begin(), x.end()
#define len(x) ll(x.size())
#define elif else if
#define eb emplace_back
#define mp make_pair
#define mt make_tuple
#define fi first
#define se second
#define stoi stoll
template <typename T, typename U>
T SUM(const vector<U> &A) {
T sum = 0;
for (auto &&a: A) sum += a;
return sum;
}
#define MIN(v) *min_element(all(v))
#define MAX(v) *max_element(all(v))
#define LB(c, x) distance((c).begin(), lower_bound(all(c), (x)))
#define UB(c, x) distance((c).begin(), upper_bound(all(c), (x)))
#define UNIQUE(x) sort(all(x)), x.erase(unique(all(x)), x.end()), x.shrink_to_fit()
int popcnt(int x) { return __builtin_popcount(x); }
int popcnt(u32 x) { return __builtin_popcount(x); }
int popcnt(ll x) { return __builtin_popcountll(x); }
int popcnt(u64 x) { return __builtin_popcountll(x); }
// (0, 1, 2, 3, 4) -> (-1, 0, 1, 1, 2)
int topbit(int x) { return (x == 0 ? -1 : 31 - __builtin_clz(x)); }
int topbit(u32 x) { return (x == 0 ? -1 : 31 - __builtin_clz(x)); }
int topbit(ll x) { return (x == 0 ? -1 : 63 - __builtin_clzll(x)); }
int topbit(u64 x) { return (x == 0 ? -1 : 63 - __builtin_clzll(x)); }
// (0, 1, 2, 3, 4) -> (-1, 0, 1, 0, 2)
int lowbit(int x) { return (x == 0 ? -1 : __builtin_ctz(x)); }
int lowbit(u32 x) { return (x == 0 ? -1 : __builtin_ctz(x)); }
int lowbit(ll x) { return (x == 0 ? -1 : __builtin_ctzll(x)); }
int lowbit(u64 x) { return (x == 0 ? -1 : __builtin_ctzll(x)); }
template <typename T>
T pick(deque<T> &que) {
T a = que.front();
que.pop_front();
return a;
}
template <typename T>
T pick(pq<T> &que) {
T a = que.top();
que.pop();
return a;
}
template <typename T>
T pick(pqg<T> &que) {
assert(que.size());
T a = que.top();
que.pop();
return a;
}
template <typename T>
T pick(vc<T> &que) {
assert(que.size());
T a = que.back();
que.pop_back();
return a;
}
template <typename T, typename U>
T ceil(T x, U y) {
return (x > 0 ? (x + y - 1) / y : x / y);
}
template <typename T, typename U>
T floor(T x, U y) {
return (x > 0 ? x / y : (x - y + 1) / y);
}
template <typename T, typename U>
pair<T, T> divmod(T x, U y) {
T q = floor(x, y);
return {q, x - q * y};
}
template <typename F>
ll binary_search(F check, ll ok, ll ng) {
assert(check(ok));
while (abs(ok - ng) > 1) {
auto x = (ng + ok) / 2;
tie(ok, ng) = (check(x) ? mp(x, ng) : mp(ok, x));
}
return ok;
}
template <typename F>
double binary_search_real(F check, double ok, double ng, int iter = 100) {
FOR(iter) {
double x = (ok + ng) / 2;
tie(ok, ng) = (check(x) ? mp(x, ng) : mp(ok, x));
}
return (ok + ng) / 2;
}
template <class T, class S>
inline bool chmax(T &a, const S &b) {
return (a < b ? a = b, 1 : 0);
}
template <class T, class S>
inline bool chmin(T &a, const S &b) {
return (a > b ? a = b, 1 : 0);
}
vc<int> s_to_vi(const string &S, char first_char) {
vc<int> A(S.size());
FOR(i, S.size()) { A[i] = S[i] - first_char; }
return A;
}
template <typename T, typename U>
vector<T> cumsum(vector<U> &A, int off = 1) {
int N = A.size();
vector<T> B(N + 1);
FOR(i, N) { B[i + 1] = B[i] + A[i]; }
if (off == 0) B.erase(B.begin());
return B;
}
template <typename CNT, typename T>
vc<CNT> bincount(const vc<T> &A, int size) {
vc<CNT> C(size);
for (auto &&x: A) { ++C[x]; }
return C;
}
// stable
template <typename T>
vector<int> argsort(const vector<T> &A) {
vector<int> ids(A.size());
iota(all(ids), 0);
sort(all(ids),
[&](int i, int j) { return A[i] < A[j] || (A[i] == A[j] && i < j); });
return ids;
}
// A[I[0]], A[I[1]], ...
template <typename T>
vc<T> rearrange(const vc<T> &A, const vc<int> &I) {
int n = len(I);
vc<T> B(n);
FOR(i, n) B[i] = A[I[i]];
return B;
}
#line 1 "library/other/io.hpp"
// based on yosupo's fastio
#include <unistd.h>
namespace fastio {
// クラスが read(), print() を持っているかを判定するメタ関数
struct has_write_impl {
template <class T>
static auto check(T &&x) -> decltype(x.write(), std::true_type{});
template <class T>
static auto check(...) -> std::false_type;
};
template <class T>
class has_write : public decltype(has_write_impl::check<T>(std::declval<T>())) {
};
struct has_read_impl {
template <class T>
static auto check(T &&x) -> decltype(x.read(), std::true_type{});
template <class T>
static auto check(...) -> std::false_type;
};
template <class T>
class has_read : public decltype(has_read_impl::check<T>(std::declval<T>())) {};
struct Scanner {
FILE *fp;
char line[(1 << 15) + 1];
size_t st = 0, ed = 0;
void reread() {
memmove(line, line + st, ed - st);
ed -= st;
st = 0;
ed += fread(line + ed, 1, (1 << 15) - ed, fp);
line[ed] = '\0';
}
bool succ() {
while (true) {
if (st == ed) {
reread();
if (st == ed) return false;
}
while (st != ed && isspace(line[st])) st++;
if (st != ed) break;
}
if (ed - st <= 50) {
bool sep = false;
for (size_t i = st; i < ed; i++) {
if (isspace(line[i])) {
sep = true;
break;
}
}
if (!sep) reread();
}
return true;
}
template <class T, enable_if_t<is_same<T, string>::value, int> = 0>
bool read_single(T &ref) {
if (!succ()) return false;
while (true) {
size_t sz = 0;
while (st + sz < ed && !isspace(line[st + sz])) sz++;
ref.append(line + st, sz);
st += sz;
if (!sz || st != ed) break;
reread();
}
return true;
}
template <class T, enable_if_t<is_integral<T>::value, int> = 0>
bool read_single(T &ref) {
if (!succ()) return false;
bool neg = false;
if (line[st] == '-') {
neg = true;
st++;
}
ref = T(0);
while (isdigit(line[st])) { ref = 10 * ref + (line[st++] & 0xf); }
if (neg) ref = -ref;
return true;
}
template <typename T,
typename enable_if<has_read<T>::value>::type * = nullptr>
inline bool read_single(T &x) {
x.read();
return true;
}
bool read_single(double &ref) {
string s;
if (!read_single(s)) return false;
ref = std::stod(s);
return true;
}
bool read_single(char &ref) {
string s;
if (!read_single(s) || s.size() != 1) return false;
ref = s[0];
return true;
}
template <class T>
bool read_single(vector<T> &ref) {
for (auto &d: ref) {
if (!read_single(d)) return false;
}
return true;
}
template <class T, class U>
bool read_single(pair<T, U> &p) {
return (read_single(p.first) && read_single(p.second));
}
template <size_t N = 0, typename T>
void read_single_tuple(T &t) {
if constexpr (N < std::tuple_size<T>::value) {
auto &x = std::get<N>(t);
read_single(x);
read_single_tuple<N + 1>(t);
}
}
template <class... T>
bool read_single(tuple<T...> &tpl) {
read_single_tuple(tpl);
return true;
}
void read() {}
template <class H, class... T>
void read(H &h, T &... t) {
bool f = read_single(h);
assert(f);
read(t...);
}
Scanner(FILE *fp) : fp(fp) {}
};
struct Printer {
Printer(FILE *_fp) : fp(_fp) {}
~Printer() { flush(); }
static constexpr size_t SIZE = 1 << 15;
FILE *fp;
char line[SIZE], small[50];
size_t pos = 0;
void flush() {
fwrite(line, 1, pos, fp);
pos = 0;
}
void write(const char &val) {
if (pos == SIZE) flush();
line[pos++] = val;
}
template <class T, enable_if_t<is_integral<T>::value, int> = 0>
void write(T val) {
if (pos > (1 << 15) - 50) flush();
if (val == 0) {
write('0');
return;
}
if (val < 0) {
write('-');
val = -val; // todo min
}
size_t len = 0;
while (val) {
small[len++] = char(0x30 | (val % 10));
val /= 10;
}
for (size_t i = 0; i < len; i++) { line[pos + i] = small[len - 1 - i]; }
pos += len;
}
void write(const string &s) {
for (char c: s) write(c);
}
void write(const char *s) {
size_t len = strlen(s);
for (size_t i = 0; i < len; i++) write(s[i]);
}
void write(const double &x) {
ostringstream oss;
oss << fixed << setprecision(15) << x;
string s = oss.str();
write(s);
}
void write(const long double &x) {
ostringstream oss;
oss << fixed << setprecision(15) << x;
string s = oss.str();
write(s);
}
template <typename T,
typename enable_if<has_write<T>::value>::type * = nullptr>
inline void write(T &x) {
x.write();
}
template <class T>
void write(const vector<T> &val) {
auto n = val.size();
for (size_t i = 0; i < n; i++) {
if (i) write(' ');
write(val[i]);
}
}
template <class T, class U>
void write(const pair<T, U> val) {
write(val.first);
write(' ');
write(val.second);
}
template <size_t N = 0, typename T>
void write_tuple(const T t) {
if constexpr (N < std::tuple_size<T>::value) {
if constexpr (N > 0) { write(' '); }
const auto x = std::get<N>(t);
write(x);
write_tuple<N + 1>(t);
}
}
template <class... T>
bool write(tuple<T...> tpl) {
write_tuple(tpl);
return true;
}
template <class T, size_t S>
void write(const array<T, S> &val) {
auto n = val.size();
for (size_t i = 0; i < n; i++) {
if (i) write(' ');
write(val[i]);
}
}
void write(i128 val) {
string s;
bool negative = 0;
if (val < 0) {
negative = 1;
val = -val;
}
while (val) {
s += '0' + int(val % 10);
val /= 10;
}
if (negative) s += "-";
reverse(all(s));
if (len(s) == 0) s = "0";
write(s);
}
};
Scanner scanner = Scanner(stdin);
Printer printer = Printer(stdout);
void flush() { printer.flush(); }
void print() { printer.write('\n'); }
template <class Head, class... Tail>
void print(Head &&head, Tail &&... tail) {
printer.write(head);
if (sizeof...(Tail)) printer.write(' ');
print(forward<Tail>(tail)...);
}
void read() {}
template <class Head, class... Tail>
void read(Head &head, Tail &... tail) {
scanner.read(head);
read(tail...);
}
} // namespace fastio
using fastio::print;
using fastio::flush;
using fastio::read;
#define INT(...) \
int __VA_ARGS__; \
read(__VA_ARGS__)
#define LL(...) \
ll __VA_ARGS__; \
read(__VA_ARGS__)
#define STR(...) \
string __VA_ARGS__; \
read(__VA_ARGS__)
#define CHAR(...) \
char __VA_ARGS__; \
read(__VA_ARGS__)
#define DBL(...) \
double __VA_ARGS__; \
read(__VA_ARGS__)
#define VEC(type, name, size) \
vector<type> name(size); \
read(name)
#define VV(type, name, h, w) \
vector<vector<type>> name(h, vector<type>(w)); \
read(name)
void YES(bool t = 1) { print(t ? "YES" : "NO"); }
void NO(bool t = 1) { YES(!t); }
void Yes(bool t = 1) { print(t ? "Yes" : "No"); }
void No(bool t = 1) { Yes(!t); }
void yes(bool t = 1) { print(t ? "yes" : "no"); }
void no(bool t = 1) { yes(!t); }
#line 2 "library/mod/modint.hpp"
template <int mod>
struct modint {
int val;
constexpr modint(ll x = 0) noexcept {
if (0 <= x && x < mod)
val = x;
else {
x %= mod;
val = (x < 0 ? x + mod : x);
}
}
bool operator<(const modint &other) const {
return val < other.val;
} // To use std::map
modint &operator+=(const modint &p) {
if ((val += p.val) >= mod) val -= mod;
return *this;
}
modint &operator-=(const modint &p) {
if ((val += mod - p.val) >= mod) val -= mod;
return *this;
}
modint &operator*=(const modint &p) {
val = (int)(1LL * val * p.val % mod);
return *this;
}
modint &operator/=(const modint &p) {
*this *= p.inverse();
return *this;
}
modint operator-() const { return modint(-val); }
modint operator+(const modint &p) const { return modint(*this) += p; }
modint operator-(const modint &p) const { return modint(*this) -= p; }
modint operator*(const modint &p) const { return modint(*this) *= p; }
modint operator/(const modint &p) const { return modint(*this) /= p; }
bool operator==(const modint &p) const { return val == p.val; }
bool operator!=(const modint &p) const { return val != p.val; }
modint inverse() const {
int a = val, b = mod, u = 1, v = 0, t;
while (b > 0) {
t = a / b;
swap(a -= t * b, b), swap(u -= t * v, v);
}
return modint(u);
}
modint pow(int64_t n) const {
modint ret(1), mul(val);
while (n > 0) {
if (n & 1) ret *= mul;
mul *= mul;
n >>= 1;
}
return ret;
}
void write() { fastio::printer.write(val); }
void read() { fastio::scanner.read(val); }
static constexpr int get_mod() { return mod; }
};
struct ArbitraryModInt {
static constexpr bool is_modint = true;
int val;
ArbitraryModInt() : val(0) {}
ArbitraryModInt(int64_t y)
: val(y >= 0 ? y % get_mod()
: (get_mod() - (-y) % get_mod()) % get_mod()) {}
bool operator<(const ArbitraryModInt &other) const {
return val < other.val;
} // To use std::map<ArbitraryModInt, T>
static int &get_mod() {
static int mod = 0;
return mod;
}
static void set_mod(int md) { get_mod() = md; }
ArbitraryModInt &operator+=(const ArbitraryModInt &p) {
if ((val += p.val) >= get_mod()) val -= get_mod();
return *this;
}
ArbitraryModInt &operator-=(const ArbitraryModInt &p) {
if ((val += get_mod() - p.val) >= get_mod()) val -= get_mod();
return *this;
}
ArbitraryModInt &operator*=(const ArbitraryModInt &p) {
long long a = (long long)val * p.val;
int xh = (int)(a >> 32), xl = (int)a, d, m;
asm("divl %4; \n\t" : "=a"(d), "=d"(m) : "d"(xh), "a"(xl), "r"(get_mod()));
val = m;
return *this;
}
ArbitraryModInt &operator/=(const ArbitraryModInt &p) {
*this *= p.inverse();
return *this;
}
ArbitraryModInt operator-() const { return ArbitraryModInt(get_mod() - val); }
ArbitraryModInt operator+(const ArbitraryModInt &p) const {
return ArbitraryModInt(*this) += p;
}
ArbitraryModInt operator-(const ArbitraryModInt &p) const {
return ArbitraryModInt(*this) -= p;
}
ArbitraryModInt operator*(const ArbitraryModInt &p) const {
return ArbitraryModInt(*this) *= p;
}
ArbitraryModInt operator/(const ArbitraryModInt &p) const {
return ArbitraryModInt(*this) /= p;
}
bool operator==(const ArbitraryModInt &p) const { return val == p.val; }
bool operator!=(const ArbitraryModInt &p) const { return val != p.val; }
ArbitraryModInt inverse() const {
int a = val, b = get_mod(), u = 1, v = 0, t;
while (b > 0) {
t = a / b;
swap(a -= t * b, b), swap(u -= t * v, v);
}
return ArbitraryModInt(u);
}
ArbitraryModInt pow(int64_t n) const {
ArbitraryModInt ret(1), mul(val);
while (n > 0) {
if (n & 1) ret *= mul;
mul *= mul;
n >>= 1;
}
return ret;
}
void write() { fastio::printer.write(val); }
void read() { fastio::scanner.read(val); }
};
template <typename mint>
mint inv(int n) {
static const int mod = mint::get_mod();
static vector<mint> dat = {0, 1};
assert(0 <= n);
if (n >= mod) n %= mod;
while (int(dat.size()) <= n) {
int k = dat.size();
auto q = (mod + k - 1) / k;
int r = k * q - mod;
dat.emplace_back(dat[r] * mint(q));
}
return dat[n];
}
template <typename mint>
mint fact(int n) {
static const int mod = mint::get_mod();
static vector<mint> dat = {1, 1};
assert(0 <= n);
if (n >= mod) return 0;
while (int(dat.size()) <= n) {
int k = dat.size();
dat.emplace_back(dat[k - 1] * mint(k));
}
return dat[n];
}
template <typename mint>
mint fact_inv(int n) {
static const int mod = mint::get_mod();
static vector<mint> dat = {1, 1};
assert(-1 <= n && n < mod);
if (n == -1) return mint(0);
while (int(dat.size()) <= n) {
int k = dat.size();
dat.emplace_back(dat[k - 1] * inv<mint>(k));
}
return dat[n];
}
template <class mint, class... Ts>
mint fact_invs(Ts... xs) {
return (mint(1) * ... * fact_inv<mint>(xs));
}
template <typename mint, class Head, class... Tail>
mint multinomial(Head &&head, Tail &&... tail) {
return fact<mint>(head) * fact_invs<mint>(std::forward<Tail>(tail)...);
}
template <typename mint>
mint C_dense(int n, int k) {
static vvc<mint> C;
static int H = 0, W = 0;
auto calc = [&](int i, int j) -> mint {
if (i == 0) return (j == 0 ? mint(1) : mint(0));
return C[i - 1][j] + (j ? C[i - 1][j - 1] : 0);
};
if (W <= k) {
FOR(i, H) {
C[i].resize(k + 1);
FOR(j, W, k + 1) { C[i][j] = calc(i, j); }
}
W = k + 1;
}
if (H <= n) {
C.resize(n + 1);
FOR(i, H, n + 1) {
C[i].resize(W);
FOR(j, W) { C[i][j] = calc(i, j); }
}
H = n + 1;
}
return C[n][k];
}
template <typename mint, bool large = false, bool dense = false>
mint C(ll n, ll k) {
assert(n >= 0);
if (k < 0 || n < k) return 0;
if (dense) return C_dense<mint>(n, k);
if (!large) return fact<mint>(n) * fact_inv<mint>(k) * fact_inv<mint>(n - k);
k = min(k, n - k);
mint x(1);
FOR(i, k) { x *= mint(n - i); }
x *= fact_inv<mint>(k);
return x;
}
template <typename mint, bool large = false>
mint C_inv(ll n, ll k) {
assert(n >= 0);
assert(0 <= k && k <= n);
if (!large) return fact_inv<mint>(n) * fact<mint>(k) * fact<mint>(n - k);
return mint(1) / C<mint, 1>(n, k);
}
// [x^d] (1-x) ^ {-n} の計算
template <typename mint, bool large = false, bool dense = false>
mint C_negative(ll n, ll d) {
assert(n >= 0);
if (d < 0) return mint(0);
if (n == 0) { return (d == 0 ? mint(1) : mint(0)); }
return C<mint, large, dense>(n + d - 1, d);
}
using modint107 = modint<1000000007>;
using modint998 = modint<998244353>;
using amint = ArbitraryModInt;
#line 4 "main.cpp"
constexpr int mod = 998244353;
int DP[510][510];
int dp[510][510];
void solve() {
using T4 = tuple<int, int, int, int>;
INT(Q, LIM);
vc<T4> dat1, dat2;
FOR(Q) {
LL(a, b, c, d);
--a, --b, --c, --d;
assert(a < c);
if (b < d) dat1.eb(a, b, c, d);
if (b > d) dat2.eb(a, LIM - 1 - b, c, LIM - 1 - d);
}
ll ANS = 0;
{
ll x = LIM;
ANS += x * x % mod * x % mod * (x - 1) % mod * (x + 1) % mod;
while (ANS % 3 != 0) ANS += mod;
ANS /= 3;
}
auto solve = [&](vc<T4> dat) -> void {
const int N = len(dat);
// (x1,y1) について昇順に並べる
sort(all(dat));
// DP[i][j] := 橋 i, ..., j と使う場合の最大個数
auto can = [&](int i, int j) -> bool {
auto [a1, b1, c1, d1] = dat[i];
auto [a2, b2, c2, d2] = dat[j];
return c1 <= a2 && d1 <= b2;
};
FOR(i, N) FOR(j, N) DP[i][j] = 0;
FOR(i, N) {
DP[i][i] = 1;
FOR(j, i, N) FOR(k, j + 1, N) {
if (DP[i][j] && can(j, k)) chmax(DP[i][k], DP[i][j] + 1);
}
}
// end point で座圧
vc<int> X = {LIM}, Y = {LIM};
for (auto&& [a, b, c, d]: dat) { X.eb(c), Y.eb(d); }
UNIQUE(X), UNIQUE(Y);
for (auto&& [a, b, c, d]: dat) { c = LB(X, c), d = LB(Y, d); }
// ix 昇順に走査する。
// dp[iy][k] := 橋 k を最初に使った場合に領域 (ix, iy) までに使える個数
FOR(i, len(Y)) FOR(j, N) dp[i][j] = 0;
FOR(ix, len(X) - 1) {
FOR(j, N) {
auto [a, b, c, d] = dat[j];
if (c != ix) continue;
FOR(k, j + 1) chmax(dp[d][k], DP[k][j]);
}
FOR(iy, len(Y) - 1) { FOR(k, N) chmax(dp[iy + 1][k], dp[iy][k]); }
FOR(iy, len(Y) - 1) {
// 直方体の和集合の体積みたいな話になる。のだが、
// 高さが t+1 の直方体は必ず高さ t の subrectangle になるので
// 高さごとに独立に断面積を足していけばよい。
vvc<pair<int, int>> rectangles(N + 1);
FOR(k, N) {
int t = dp[iy][k];
if (t == 0) continue;
auto [a, b, c, d] = dat[k];
rectangles[t].eb(a + 1, b + 1);
}
ll volume = 0;
FOR(t, 1, N + 1) {
ll area = 0;
if (rectangles[t].empty()) break;
auto& XY = rectangles[t];
// 既に x 順にソートされている
// 後ろにある高さで chmax する
int M = len(XY);
int my = 0;
FOR_R(j, M) { chmax(my, XY[j].se), XY[j].se = my; }
int px = 0;
FOR(j, M) {
auto [x, y] = XY[j];
area += ll(x - px) * y;
px = x;
}
volume += area % mod;
}
volume %= mod;
int dx = X[ix + 1] - X[ix], dy = Y[iy + 1] - Y[iy];
ANS -= volume * dx % mod * dy % mod;
}
}
};
solve(dat1);
solve(dat2);
ANS %= mod;
if (ANS < 0) ANS += mod;
print(ANS);
}
signed main() {
solve();
return 0;
}
詳細信息
Test #1:
score: 100
Accepted
time: 3ms
memory: 3556kb
input:
2 2 1 1 2 2 1 2 2 1
output:
6
result:
ok answer is '6'
Test #2:
score: 0
Accepted
time: 2ms
memory: 3364kb
input:
0 1000000000
output:
916520226
result:
ok answer is '916520226'
Test #3:
score: 0
Accepted
time: 2ms
memory: 3472kb
input:
5 5 1 1 3 3 3 3 5 1 3 3 4 5 3 3 5 4 1 5 3 3
output:
946
result:
ok answer is '946'
Test #4:
score: 0
Accepted
time: 2ms
memory: 3772kb
input:
200 5 1 1 4 2 2 5 4 4 2 3 4 2 2 4 3 5 1 4 4 2 2 5 4 2 1 2 4 4 1 2 2 4 1 4 5 1 3 4 5 1 4 2 5 1 2 2 5 4 3 2 5 1 3 1 5 2 4 2 5 3 1 3 5 1 3 4 4 5 2 2 4 3 2 3 5 4 1 4 5 3 2 2 3 1 2 5 3 3 1 1 5 3 4 4 5 5 1 3 4 4 4 3 5 1 2 3 3 4 3 4 4 2 1 4 4 5 2 1 4 4 1 3 5 2 1 1 3 3 1 5 3 1 1 1 3 5 1 4 3 5 4 5 5 4 1 1 4 ...
output:
708
result:
ok answer is '708'
Test #5:
score: 0
Accepted
time: 0ms
memory: 3864kb
input:
500 10 5 6 7 10 1 3 8 10 3 3 4 9 2 10 10 2 9 4 10 10 5 4 7 8 7 1 10 7 3 1 7 10 5 2 8 9 6 3 7 10 3 10 7 9 4 9 5 1 2 5 3 3 7 10 8 2 7 7 9 8 6 6 8 3 5 10 8 8 1 1 5 5 3 3 10 5 5 5 7 6 3 8 4 7 6 7 7 5 7 3 10 9 5 3 9 4 4 6 10 5 1 5 9 10 5 6 9 7 3 10 10 3 1 2 5 7 4 6 5 1 3 1 8 5 5 8 8 9 1 8 4 3 6 4 7 10 7 ...
output:
27373
result:
ok answer is '27373'
Test #6:
score: 0
Accepted
time: 1ms
memory: 4048kb
input:
500 30 3 13 20 29 14 5 16 25 2 29 9 15 23 30 24 9 1 18 24 28 4 16 5 2 3 29 30 25 4 8 24 19 8 26 10 24 20 14 26 25 15 8 25 25 5 13 18 28 3 30 29 10 14 26 25 11 11 19 16 4 9 4 29 30 15 10 16 8 2 29 12 2 11 22 20 28 4 10 28 1 24 17 30 1 8 26 27 9 15 25 30 14 16 20 24 17 9 23 12 13 9 16 25 28 2 15 8 16 ...
output:
7717993
result:
ok answer is '7717993'
Test #7:
score: 0
Accepted
time: 13ms
memory: 4172kb
input:
500 100 25 55 55 43 14 22 84 5 57 7 79 15 63 9 86 23 22 3 53 97 2 22 64 65 32 52 66 30 76 37 79 22 46 100 76 22 21 78 78 44 29 41 92 55 43 14 46 3 14 97 42 1 16 7 35 64 15 27 29 3 11 92 92 70 4 13 66 2 3 38 55 82 41 94 83 44 52 90 100 82 6 100 99 70 18 38 24 22 74 17 98 20 17 94 44 82 33 97 48 19 12...
output:
291628571
result:
ok answer is '291628571'
Test #8:
score: 0
Accepted
time: 1ms
memory: 4608kb
input:
500 8 2 4 8 2 3 7 5 4 2 6 8 1 4 8 5 5 6 6 7 5 2 6 5 5 1 6 8 5 6 5 7 3 4 8 5 7 5 7 6 5 1 6 4 5 2 3 4 2 2 8 8 6 3 8 4 3 5 6 7 2 7 8 8 3 1 8 4 7 1 6 6 1 1 8 7 1 1 4 3 3 2 3 3 1 1 4 5 1 1 8 5 4 7 7 8 5 2 7 4 1 3 7 4 3 2 3 5 1 3 7 8 1 4 7 5 5 6 6 8 3 2 7 5 1 2 5 4 3 5 4 8 2 4 5 8 3 2 3 4 1 2 8 3 2 5 6 8 ...
output:
9321
result:
ok answer is '9321'
Test #9:
score: 0
Accepted
time: 150ms
memory: 4544kb
input:
500 1000000000 228604634 522874974 789854111 585676486 340802063 175643637 661594207 749079321 490078806 844144515 583746323 707696611 833939453 901516824 867397264 848066012 553537526 886003963 679012061 187030606 351500555 847099665 751201742 855105070 169763646 729114554 248951243 211939611 17040...
output:
230090667
result:
ok answer is '230090667'
Test #10:
score: 0
Accepted
time: 514ms
memory: 5500kb
input:
500 1000000000 536804949 618264275 757262973 133194920 206604343 420304040 244005624 331707206 64548973 877773848 685024560 565782395 13572244 271309598 835979107 128627415 128103153 561746493 703898577 9276472 209282309 997406956 216339996 279878227 386095652 999498735 908610032 582414132 232191790...
output:
404991176
result:
ok answer is '404991176'
Test #11:
score: 0
Accepted
time: 526ms
memory: 5536kb
input:
500 1000000000 435165109 887707979 541968631 834720917 43164344 595179931 731392283 541750474 51147932 885859385 525997101 813310992 581745995 569929983 666239343 349298365 720599913 330436249 751561895 84593980 254142704 924477087 706739688 760929039 282091849 414650019 853811117 121534462 21407507...
output:
174105246
result:
ok answer is '174105246'
Test #12:
score: 0
Accepted
time: 524ms
memory: 5496kb
input:
500 1000000000 334968963 60182667 683993047 330063742 372714145 727060351 391638535 972082352 15288009 443033033 549932294 626507494 551292358 201286324 844192128 989162325 138957062 834473180 233314539 840742618 774917762 293038146 784290713 868100668 88362426 108423246 90763875 635080794 197409326...
output:
819654628
result:
ok answer is '819654628'
Test #13:
score: 0
Accepted
time: 580ms
memory: 5540kb
input:
500 1000000000 407797655 600906761 451028876 557753318 739109786 505834673 914488662 267694229 21613693 815099602 741520301 86754775 749426136 864500481 989644055 760004108 97929570 281277866 645537954 194083134 386298407 900097354 590149576 876589970 225981751 604462892 313700311 201620926 13512935...
output:
704804476
result:
ok answer is '704804476'
Test #14:
score: 0
Accepted
time: 146ms
memory: 4412kb
input:
500 1000000000 136588729 322381152 198423052 586895024 146201252 78771798 320963978 33171878 103014217 582579333 112482565 472327049 363500012 171569343 779799989 210605961 916348434 897403875 958218658 848653603 81959275 288412262 293263271 877464982 155884974 409342051 490632310 353856648 42868173...
output:
701057894
result:
ok answer is '701057894'
Test #15:
score: 0
Accepted
time: 148ms
memory: 4708kb
input:
500 1000000000 70732466 818210159 101241592 180120566 551559764 430141447 558477026 919623562 842854549 898003264 988655980 690377539 365038538 842566580 988616538 612555368 119137999 522482797 776356145 341894154 134943863 753491473 621956497 857574689 860979233 313689040 912231580 819779431 253383...
output:
849305849
result:
ok answer is '849305849'
Test #16:
score: 0
Accepted
time: 144ms
memory: 4624kb
input:
500 1000000000 76067493 226360208 588463712 997370258 247139391 228988779 876938260 628658287 173490201 249999131 402004522 332729284 73514885 82656638 357464837 702514607 288650085 526722777 582817141 741491871 859774917 73498480 878952996 868608989 248586909 115745356 485233299 599896403 302539166...
output:
980753674
result:
ok answer is '980753674'
Test #17:
score: -100
Time Limit Exceeded
input:
500 919069957 742507159 740217847 742778031 741238898 320301045 312370945 321929532 313537690 344928356 347275650 349920032 348402734 128430402 156747983 128702472 159673979 89940237 122339622 90602165 123930504 638094551 604903042 638437986 606101004 118489244 152414022 121260981 154139858 41785067...