結果
問題 |
No.3207 Digital Font
|
ユーザー |
![]() |
提出日時 | 2025-07-19 00:32:08 |
言語 | C++23 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 343 ms / 3,000 ms |
コード長 | 5,311 bytes |
コンパイル時間 | 4,264 ms |
コンパイル使用メモリ | 330,884 KB |
実行使用メモリ | 19,332 KB |
最終ジャッジ日時 | 2025-07-19 00:32:24 |
合計ジャッジ時間 | 14,186 ms |
ジャッジサーバーID (参考情報) |
judge5 / judge1 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 2 |
other | AC * 38 |
ソースコード
#include<bits/stdc++.h> namespace { #pragma GCC diagnostic ignored "-Wunused-function" #include<atcoder/all> #pragma GCC diagnostic warning "-Wunused-function" using namespace std; using namespace atcoder; #define rep(i,n) for(int i = 0; i < (int)(n); i++) #define rrep(i,n) for(int i = (int)(n) - 1; i >= 0; i--) #define all(x) begin(x), end(x) #define rall(x) rbegin(x), rend(x) template<class T> bool chmax(T& a, const T& b) { if (a < b) { a = b; return true; } else return false; } template<class T> bool chmin(T& a, const T& b) { if (b < a) { a = b; return true; } else return false; } using ll = long long; using P = pair<int,int>; using VI = vector<int>; using VVI = vector<VI>; using VL = vector<ll>; using VVL = vector<VL>; class mint61 { using ull = unsigned long long; using ui128 = __uint128_t; public: static constexpr unsigned long long mod = (1ULL << 61) - 1; ull v = 0; constexpr mint61() {} explicit constexpr mint61(ull x) { v = (x >> 61) + (x & mod); if (v >= mod) v -= mod; } static constexpr mint61 raw(ull x) { mint61 res; res.v = x; return res; } friend constexpr mint61 operator+(mint61 lhs, mint61 rhs) { auto res = lhs.v + rhs.v; return raw(res < mod ? res : res - mod); } friend constexpr mint61 operator-(mint61 lhs, mint61 rhs) { return raw(lhs.v >= rhs.v ? lhs.v - rhs.v : mod + lhs.v - rhs.v); } static constexpr ull multiply_loose_mod(mint61 lhs, mint61 rhs) { // ab = q(m+1)+r = qm+q+r // q+r = ab-qm = ab-floor(ab/(m+1))m < ab-(ab/(m+1)-1)m = ab/(m+1)+m <= // (m-1)^2/(m+1)+m = 2m-3+4/(m+1) auto mul = ui128(lhs.v) * rhs.v; return ull(mul >> 61) + ull(mul & mod); } friend constexpr mint61 operator*(mint61 lhs, mint61 rhs) { auto res = multiply_loose_mod(lhs, rhs); return raw(res < mod ? res : res - mod); } mint61& operator+=(mint61 rhs) { return *this = *this + rhs; } mint61& operator-=(mint61 rhs) { return *this = *this - rhs; } mint61& operator*=(mint61 rhs) { return *this = *this * rhs; } friend constexpr bool operator==(const mint61& lhs, const mint61& rhs) { return lhs.v == rhs.v; } friend ostream& operator<<(ostream& os, mint61 x) { return os << x.v; } }; std::mt19937 RNG(std::chrono::system_clock::now().time_since_epoch().count()); unsigned long long RULL(unsigned long long L, unsigned long long R) { assert(L < R); return std::uniform_int_distribution<unsigned long long>(L, R - 1)(RNG); } using mint = mint61; const mint B = mint(RULL(1, mint61::mod)); constexpr int MXSIZE = 100010; mint powB[MXSIZE + 1], powB2wx[MXSIZE + 1]; auto init_Bs = [] { powB[0] = mint::raw(1); for (int i = 0; i < MXSIZE; i++) powB[i + 1] = powB[i] * B; return false; }(); template <class T> struct V { int i, j; T v; }; struct Q { int il, ir, jl, jr; }; template <class T, class ResT=T> auto rectangle_sum(vector<V<T>> points, vector<Q> queries) { ranges::sort(points, {}, &V<T>::i); vector<int> vc; vc.reserve(points.size()); for (const auto& p : points) vc.emplace_back(p.j); ranges::sort(vc); vc.erase(unique(vc.begin(), vc.end()), vc.end()); struct Ask { int i, iq; bool plus; }; vector<Ask> asks(2 * queries.size()); for (int iq = 0; iq < ssize(queries); iq++) { asks[2 * iq] = {queries[iq].il, iq, false}; asks[2 * iq + 1] = {queries[iq].ir, iq, true}; } ranges::sort(asks, {}, &Ask::i); const int sz = vc.size(); vector<ResT> ft(sz); auto add = [&](int p, T x) { assert(0 <= p && p < sz); for (p++; p <= sz; p += p & -p) ft[p-1] += x; }; auto sum = [&](int r) { assert(0 <= r && r <= sz); ResT s{}; for (; r > 0; r -= r & -r) s += ft[r-1]; return s; }; int ptr = 0; vector<ResT> ans(queries.size()); for (auto [i, iq, plus] : asks) { for (; ptr < ssize(points) && points[ptr].i < i; ptr++) { add(ranges::lower_bound(vc, points[ptr].j) - vc.begin(), points[ptr].v); } int l = ranges::lower_bound(vc, queries[iq].jl) - vc.begin(); int r = ranges::lower_bound(vc, queries[iq].jr) - vc.begin(); if (plus) ans[iq] += sum(r) - sum(l); else ans[iq] -= sum(r) - sum(l); } return ans; } } int main() { ios::sync_with_stdio(false); cin.tie(0); int h, w, n; cin >> h >> w >> n; powB2wx[0] = mint::raw(1); rep(i, MXSIZE) powB2wx[i+1] = powB2wx[i] * powB[w]; auto f = [](int x) { if (x == 6) return 9; if (x == 9) return 6; return x; }; vector<V<mint>> points1(n), points2(n); rep(t, n) { int i, j, x; cin >> i >> j >> x; i--, j--; points1[t] = {i, j, mint::raw(x) * powB2wx[i] * powB[j]}; i = h - 1 - i, j = w - 1 - j, x = f(x); points2[t] = {i, j, mint::raw(x) * powB2wx[i] * powB[j]}; } int q; cin >> q; vector<Q> queries1(q), queries2(q); for (int t = 0; t < q; t++) { int il, jl, ir, jr; cin >> il >> jl >> ir >> jr; il--, jl--; queries1[t] = {il, ir, jl, jr}; queries2[t] = {h-ir, h-il, w-jr, w-jl}; } auto sum1 = rectangle_sum(points1, queries1); auto sum2 = rectangle_sum(points2, queries2); for (int t = 0; t < q; t++) { mint v1 = sum1[t] * powB2wx[h - queries1[t].il] * powB[w - queries1[t].jl]; mint v2 = sum2[t] * powB2wx[h - queries2[t].il] * powB[w - queries2[t].jl]; cout << (v1 == v2 ? "Yes\n" : "No\n"); } }