제출 #1150302

#제출 시각아이디문제언어결과실행 시간메모리
1150302Perl32Crossing (JOI21_crossing)C++20
26 / 100
256 ms30312 KiB
//I wrote this code 4 u <3 #include <bits/stdc++.h> using namespace std; using ll = long long; #ifdef LOCAL #include "algo/debug.h" #else #define debug(...) 42 #endif template <typename T> T inverse(T a, T m) { T u = 0, v = 1; while (a != 0) { T t = m / a; m -= t * a; swap(a, m); u -= t * v; swap(u, v); } assert(m == 1); return u; } template <typename T> class Modular { public: using Type = typename decay<decltype(T::value)>::type; constexpr Modular() : value() {} template <typename U> Modular(const U& x) { value = normalize(x); } template <typename U> static Type normalize(const U& x) { Type v; if (-mod() <= x && x < mod()) v = static_cast<Type>(x); else v = static_cast<Type>(x % mod()); if (v < 0) v += mod(); return v; } const Type& operator()() const { return value; } template <typename U> explicit operator U() const { return static_cast<U>(value); } constexpr static Type mod() { return T::value; } Modular& operator+=(const Modular& other) { if ((value += other.value) >= mod()) value -= mod(); return *this; } Modular& operator-=(const Modular& other) { if ((value -= other.value) < 0) value += mod(); return *this; } template <typename U> Modular& operator+=(const U& other) { return *this += Modular(other); } template <typename U> Modular& operator-=(const U& other) { return *this -= Modular(other); } Modular& operator++() { return *this += 1; } Modular& operator--() { return *this -= 1; } Modular operator++(int) { Modular result(*this); *this += 1; return result; } Modular operator--(int) { Modular result(*this); *this -= 1; return result; } Modular operator-() const { return Modular(-value); } template <typename U = T> typename enable_if<is_same<typename Modular<U>::Type, int>::value, Modular>::type& operator*=(const Modular& rhs) { value = normalize(static_cast<int64_t>(value) * static_cast<int64_t>(rhs.value)); return *this; } template <typename U = T> typename enable_if<is_same<typename Modular<U>::Type, long long>::value, Modular>::type& operator*=(const Modular& rhs) { long long q = static_cast<long long>(static_cast<long double>(value) * rhs.value / mod()); value = normalize(value * rhs.value - q * mod()); return *this; } template <typename U = T> typename enable_if<!is_integral<typename Modular<U>::Type>::value, Modular>::type& operator*=(const Modular& rhs) { value = normalize(value * rhs.value); return *this; } Modular& operator/=(const Modular& other) { return *this *= Modular(inverse(other.value, mod())); } friend const Type& abs(const Modular& x) { return x.value; } template <typename U> friend bool operator==(const Modular<U>& lhs, const Modular<U>& rhs); template <typename U> friend bool operator<(const Modular<U>& lhs, const Modular<U>& rhs); template <typename V, typename U> friend V& operator>>(V& stream, Modular<U>& number); private: Type value; }; template <typename T> bool operator==(const Modular<T>& lhs, const Modular<T>& rhs) { return lhs.value == rhs.value; } template <typename T, typename U> bool operator==(const Modular<T>& lhs, U rhs) { return lhs == Modular<T>(rhs); } template <typename T, typename U> bool operator==(U lhs, const Modular<T>& rhs) { return Modular<T>(lhs) == rhs; } template <typename T> bool operator!=(const Modular<T>& lhs, const Modular<T>& rhs) { return !(lhs == rhs); } template <typename T, typename U> bool operator!=(const Modular<T>& lhs, U rhs) { return !(lhs == rhs); } template <typename T, typename U> bool operator!=(U lhs, const Modular<T>& rhs) { return !(lhs == rhs); } template <typename T> bool operator<(const Modular<T>& lhs, const Modular<T>& rhs) { return lhs.value < rhs.value; } template <typename T> Modular<T> operator+(const Modular<T>& lhs, const Modular<T>& rhs) { return Modular<T>(lhs) += rhs; } template <typename T, typename U> Modular<T> operator+(const Modular<T>& lhs, U rhs) { return Modular<T>(lhs) += rhs; } template <typename T, typename U> Modular<T> operator+(U lhs, const Modular<T>& rhs) { return Modular<T>(lhs) += rhs; } template <typename T> Modular<T> operator-(const Modular<T>& lhs, const Modular<T>& rhs) { return Modular<T>(lhs) -= rhs; } template <typename T, typename U> Modular<T> operator-(const Modular<T>& lhs, U rhs) { return Modular<T>(lhs) -= rhs; } template <typename T, typename U> Modular<T> operator-(U lhs, const Modular<T>& rhs) { return Modular<T>(lhs) -= rhs; } template <typename T> Modular<T> operator*(const Modular<T>& lhs, const Modular<T>& rhs) { return Modular<T>(lhs) *= rhs; } template <typename T, typename U> Modular<T> operator*(const Modular<T>& lhs, U rhs) { return Modular<T>(lhs) *= rhs; } template <typename T, typename U> Modular<T> operator*(U lhs, const Modular<T>& rhs) { return Modular<T>(lhs) *= rhs; } template <typename T> Modular<T> operator/(const Modular<T>& lhs, const Modular<T>& rhs) { return Modular<T>(lhs) /= rhs; } template <typename T, typename U> Modular<T> operator/(const Modular<T>& lhs, U rhs) { return Modular<T>(lhs) /= rhs; } template <typename T, typename U> Modular<T> operator/(U lhs, const Modular<T>& rhs) { return Modular<T>(lhs) /= rhs; } template<typename T, typename U> Modular<T> power(const Modular<T>& a, const U& b) { Modular<T> x = a, res = 1; U p = b; while (p > 0) { if (p & 1) res *= x; x *= x; p >>= 1; } return res; } template <typename T> bool IsZero(const Modular<T>& number) { return number() == 0; } template <typename T> string to_string(const Modular<T>& number) { return to_string(number()); } template <typename U, typename T> U& operator<<(U& stream, const Modular<T>& number) { return stream << number(); } template <typename U, typename T> U& operator>>(U& stream, Modular<T>& number) { typename common_type<typename Modular<T>::Type, long long>::type x; stream >> x; number.value = Modular<T>::normalize(x); return stream; } constexpr int mod = 1e9 + 7; using mint = Modular<std::integral_constant<decay<decltype(mod)>::type, mod>>; template<> struct std::hash<mint> { ll operator()(const mint& a) const { return (ll) a; } }; const int maxN = 2e5 + 2e3; const int R = 5; mint pw[maxN]; mint spw[maxN]; void precalc() { pw[0] = 1; spw[0] = 1; for (int i = 1; i < maxN; ++i) { pw[i] = pw[i - 1] * R; spw[i] = spw[i - 1] + pw[i]; } } int conv(char c) { if (c == 'J') { return 1; } else if (c == 'O') { return 2; } return 3; } struct Info { mint hsh = 0; int sz = 0; Info() = default; Info(int v) : hsh(v), sz(1) {} }; Info operator+(const Info &a, const Info &b) { Info ret; ret.hsh = a.hsh * pw[b.sz] + b.hsh; ret.sz = a.sz + b.sz; return ret; } struct Tag { bool st = 0; int v = 0; Tag() = default; explicit Tag(int _v) { st = 1; v = _v; } }; void apply(Info &a, Tag b) { if (b.st) { if (a.sz) { a.hsh = b.v * spw[a.sz - 1]; } } } void apply(Tag &a, Tag b) { if (b.st) { a = b; } } template<class Info, class Tag, class Merge = plus<Info>> class LazySegTree { public: int sz; const Merge merge; vector<Info> t; vector<Tag> tag; LazySegTree() = default; LazySegTree(int n, const Info &v = Info()) : merge(Merge()) { sz = 1; while (sz < n) sz <<= 1; t.assign(sz << 1, Info()); tag.assign(sz << 1, {}); for (int i = 0; i < n; ++i) { t[i + sz] = v; } for (int i = sz - 1; i > 0; --i) { pull(i); } } LazySegTree(const vector<Info> &a) : merge(Merge()) { sz = 1; while (sz < (int) a.size()) sz <<= 1; t.resize(sz << 1), tag.assign(sz << 1, {}); for (int i = 0; i < int(a.size()); ++i) { t[i + sz] = a[i]; } for (int i = sz - 1; i > 0; --i) { pull(i); } } void pull(int x) { t[x] = merge(t[x << 1], t[x << 1 | 1]); } void apply(int p, const Tag &v) { ::apply(t[p], v); ::apply(tag[p], v); } void push(int x) { apply(x << 1, tag[x]); apply(x << 1 | 1, tag[x]); tag[x] = Tag(); } Info get(int l, int r, int x, int lx, int rx) { if (l >= rx || lx >= r) { return Info(); } if (l <= lx && rx <= r) { return t[x]; } int m = (lx + rx) >> 1; push(x); return merge(get(l, r, x << 1, lx, m), get(l, r, x << 1 | 1, m, rx)); } Info get(int l, int r) { return get(l, r, 1, 0, sz); } Info get(int i, int x, int lx, int rx) { if (lx + 1 == rx) { return t[x]; } int m = (lx + rx) >> 1; push(x); if (i < m) return get(i, x << 1, lx, m); else return get(i, x << 1 | 1, m, rx); } Info get(int i) { return get(i, 1, 0, sz); } void upd(int l, int r, const Tag v, int x, int lx, int rx) { if (l >= rx || lx >= r) { return; } if (l <= lx && rx <= r) { apply(x, v); return; } int m = (lx + rx) >> 1; push(x); upd(l, r, v, x << 1, lx, m); upd(l, r, v, x << 1 | 1, m, rx); pull(x); } void upd(int l, int r, Tag v) { upd(l, r, v, 1, 0, sz); } void upd(int i, Info v, int x, int lx, int rx) { if (lx + 1 == rx) { t[x] = v; return; } int m = (lx + rx) >> 1; push(x); if (i < m) upd(i, v, x << 1, lx, m); else upd(i, v, x << 1 | 1, m, rx); pull(x); } void upd(int i, Info v) { upd(i, v, 1, 0, sz); } Info prod() { return t[1]; } }; signed main(int32_t argc, char *argv[]) { ios_base::sync_with_stdio(false); cin.tie(nullptr); precalc(); int n; cin >> n; vector<vector<int>> a(3, vector<int>(n)); for (auto& x : a) { for (auto& y : x) { char c; cin >> c; if (c == 'J') { y = 1; } else if (c == 'O') { y = 2; } else { y = 3; } } } auto prod = [&](int x, int y) { if (x == y) return x; return 6 - (x + y); }; const int sz = 3, msk = (1 << sz); unordered_map<mint, bool> have; vector<vector<int>> tmp(msk, vector<int>(n)); for (int i = 1; i < msk; ++i) { int bit = i & -i, id = __lg(bit), pop_cnt = __builtin_popcount(i); if (pop_cnt == 1) { tmp[i] = a[id]; } else { int pre = i ^ bit; for (int j = 0; j < n; ++j) { tmp[i][j] = prod(tmp[pre][j], a[id][j]); } } mint cur = 0; for (auto x : tmp[i]) cur = cur * R + x; // for (auto x : tmp[i]) { // if (x == 1) { // cerr << 'J'; // } else if (x == 2) { // cerr << 'O'; // } else { // cerr << 'I'; // } // } // cerr << ' ' << cur << '\n'; have[cur] = 1; } int q; cin >> q; vector<Info> t(n); for (auto& x : t) { char c; cin >> c; if (c == 'J') { x = Info(1); } else if (c == 'O') { x = Info(2); } else { x = Info(3); } } LazySegTree<Info, Tag> tt(t); cout << (have[tt.prod().hsh] ? "Yes" : "No") << '\n'; while (q--) { int l, r; char c; cin >> l >> r >> c; --l; tt.upd(l, r, Tag(conv(c))); cout << (have[tt.prod().hsh] ? "Yes" : "No") << '\n'; } } /* */
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...