結果
問題 |
No.3207 Digital Font
|
ユーザー |
|
提出日時 | 2025-07-15 19:23:06 |
言語 | C++23 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 682 ms / 3,000 ms |
コード長 | 4,309 bytes |
コンパイル時間 | 3,785 ms |
コンパイル使用メモリ | 294,516 KB |
実行使用メモリ | 30,116 KB |
最終ジャッジ日時 | 2025-07-17 02:03:39 |
合計ジャッジ時間 | 24,557 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge1 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 2 |
other | AC * 38 |
ソースコード
#include <bits/stdc++.h> using namespace std; using ll = long long; const int mod = 998244353; class mint { public: long long x; mint(long long x = 0) : x((x % mod + mod) % mod) {} mint operator-() const { return mint(-x); } mint &operator+=(const mint &a) { if ((x += a.x) >= mod) x -= mod; return *this; } mint &operator-=(const mint &a) { if ((x += mod - a.x) >= mod) x -= mod; return *this; } mint &operator*=(const mint &a) { (x *= a.x) %= mod; return *this; } mint operator+(const mint &a) const { mint res(*this); return res += a; } mint operator-(const mint &a) const { mint res(*this); return res -= a; } mint operator*(const mint &a) const { mint res(*this); return res *= a; } mint pow(ll t) const { if (!t) return 1; mint a = pow(t >> 1); a *= a; if (t & 1) a *= *this; return a; } // for prime mod mint inv() const { return pow(mod - 2); } mint &operator/=(const mint &a) { return (*this) *= a.inv(); } mint operator/(const mint &a) const { mint res(*this); return res /= a; } friend ostream &operator<<(ostream &os, const mint &m) { os << m.x; return os; } }; struct RMQ { const mint INF = 0; int n; // 葉の数 vector<mint> dat; // 完全二分木の配列 RMQ(int n_) : n(), dat(n_ * 4, INF) { // 葉の数は 2^x の形 int x = 1; while (n_ > x) { x *= 2; } n = x; } void update(int i, mint x) { i += n - 1; dat[i] += x; while (i > 0) { i = (i - 1) / 2; // parent dat[i] = dat[i * 2 + 1] + dat[i * 2 + 2]; } } // 半開区間[l,r) // the minimum element of [a,b) mint query(int a, int b) { return query_sub(a, b, 0, 0, n); } mint query_sub(int a, int b, int k, int l, int r) { if (r <= a || b <= l) { return INF; } else if (a <= l && r <= b) { return dat[k]; } else { mint vl = query_sub(a, b, k * 2 + 1, l, (l + r) / 2); mint vr = query_sub(a, b, k * 2 + 2, (l + r) / 2, r); return vl + vr; } } }; struct query { int type = INT_MAX, x = INT_MAX, y = INT_MAX, c = INT_MAX, base = 1; bool operator<(const query &other) { if (x != other.x) return x < other.x; return type < other.type; } }; vector<mint> solve(vector<query> &v, vector<ll> &memo, int h, int w, int n, int q) { RMQ seg(w + 10); vector<mint> ans(q); for (int i = 0; i < n + 4 * q; i++) { if (v[i].type == 1) { mint cost = mint(10).pow((ll)(v[i].x - 1) * h + v[i].y - 1) * mint(v[i].c); seg.update(v[i].y, cost); } else { mint now = seg.query(0, v[i].y + 1); ans[v[i].c] += now * mint(v[i].base); } } for (int i = 0; i < q; i++) ans[i] /= mint(10).pow(memo[i]); return ans; } int f(int x) { vector v = {0, 1, 2, 3, 4, 5, 9, 7, 8, 6}; return v[x]; } void input() { int h, w, n; cin >> h >> w >> n; vector<query> a, b; vector<ll> memoa, memob; for (int i = 0; i < n; i++) { query p; p.type = 1; cin >> p.x >> p.y >> p.c; a.push_back(p); p.x = h + 1 - p.x; p.y = w + 1 - p.y; p.c = f(p.c); b.push_back(p); } int q; cin >> q; for (int i = 0; i < q; i++) { int l, d, r, u; cin >> l >> d >> r >> u; a.push_back({2, r, u, i, 1}); a.push_back({2, l - 1, d - 1, i, 1}); a.push_back({2, r, d - 1, i, -1}); a.push_back({2, l - 1, u, i, -1}); memoa.push_back((ll)h * (l - 1) + d - 1); int tmp = l; l = h + 1 - r; r = h + 1 - tmp; tmp = d; d = w + 1 - u; u = w + 1 - tmp; b.push_back({2, r, u, i, 1}); b.push_back({2, l - 1, d - 1, i, 1}); b.push_back({2, r, d - 1, i, -1}); b.push_back({2, l - 1, u, i, -1}); memob.push_back((ll)h * (l - 1) + d - 1); } sort(a.begin(), a.end()); sort(b.begin(), b.end()); auto c = solve(a, memoa, h, w, n, q); auto d = solve(b, memob, h, w, n, q); for (int i = 0; i < q; i++) { if (c[i].x == d[i].x) { cout << "Yes" << endl; } else { cout << "No" << endl; } } } int main() { cin.tie(0)->sync_with_stdio(0); cout << fixed << setprecision(20); int CNT = 1; for (int i = 0; i < CNT; i++) input(); }