Submission #847996

#TimeUsernameProblemLanguageResultExecution timeMemory
847996restingModern Machine (JOI23_ho_t5)C++17
36 / 100
3058 ms863208 KiB
#include <bits/stdc++.h> using namespace std; #define int long long const int mx = 1.2e5 + 5; const int magic = 400; //const int magic = 3; namespace rmq { struct segtree { segtree* lc = 0, * rc = 0; int l, r; int v = numeric_limits<int>::max(); segtree* getmem(); segtree() : segtree(-1, -1) {}; segtree(int l, int r) : l(l), r(r) { if (l == r)return; int m = (l + r) / 2; lc = getmem(); *lc = segtree(l, m); rc = getmem(); *rc = segtree(m + 1, r); }; segtree* upd(int qi, int qv) { segtree* tr = getmem(); *tr = *this; if (qi < l || qi > r) return tr; if (l == r) { tr->v = qv; return tr; } tr->lc = lc->upd(qi, qv); tr->rc = rc->upd(qi, qv); tr->v = min(tr->lc->v, tr->rc->v); return tr; } int q(int ql, int qr) { if (ql > qr)return numeric_limits<int>::max(); if (ql > r || qr < l) return numeric_limits<int>::max(); if (ql <= l && qr >= r) return v; return min(lc->q(ql, qr), rc->q(ql, qr)); } }mem[mx * 40]; int memsz = 0;// surely enogh? segtree* segtree::getmem() { return &mem[memsz++]; } } namespace rsq { struct segtree { segtree* lc = 0, * rc = 0; int l, r; int v = 0; segtree* getmem(); segtree() : segtree(-1, -1) {}; segtree(int l, int r) : l(l), r(r) { if (l == r)return; int m = (l + r) / 2; lc = getmem(); *lc = segtree(l, m); rc = getmem(); *rc = segtree(m + 1, r); }; segtree* upd(int qi, int qv) { segtree* tr = getmem(); *tr = *this; if (qi < l || qi > r) return tr; if (l == r) { tr->v += qv; return tr; } tr->lc = lc->upd(qi, qv); tr->rc = rc->upd(qi, qv); tr->v = tr->lc->v + tr->rc->v; return tr; } int q(int ql, int qr) { if (ql > qr) return 0; if (ql > r || qr < l) return 0; if (ql <= l && qr >= r) return v; return lc->q(ql, qr) + rc->q(ql, qr); } }mem[mx * 80]; int memsz = 0;// surely enogh? segtree* segtree::getmem() { return &mem[memsz++]; } } struct bit { vector<int> b, a; vector<pair<int, int>> us; bit(int n) : b(n + 1, 0), a(n + 1, 0) {}; int q(int i) { int v = 0; for (i++; i > 0; i -= i & -i) v += b[i]; return v; } void u(int i, int v) { us.push_back({ i, v });if (i < a.size()) a[i] += v; for (i++; i < b.size(); i += i & -i) b[i] += v; } void u(int l, int r, int v) { if (l > r) return; u(l, v); u(r + 1, -v); } }; int holy[mx / magic][mx]; int32_t main() { cin.tie(0)->sync_with_stdio(0); int n, m; cin >> n >> m; string c; cin >> c; vector<int> a(m); for (auto& x : a) { cin >> x; x--; } vector<vector<int>> a2(n + 1); for (int i = 0; i < m; i++) a2[a[i]].push_back(i); vector<int> ls, rs; ls.push_back(-1); rs.push_back(n); for (int i = 0; i < n; i++) if (c[i] == 'B') ls.push_back(i); for (int i = n - 1; i >= 0; i--) if (c[i] == 'R') rs.push_back(i); vector<int> pre(n, 0); for (int i = 0; i < n; i++) { if (i) pre[i] = pre[i - 1]; pre[i] += c[i] == 'R'; } auto sm = [&](int l, int r) { if (l > r) return 0LL; if (l > n) l = n; if (r > n - 1) r = n - 1; if (r < 0) return 0LL; if (l <= 0) return pre[r]; return pre[r] - pre[l - 1]; }; //very necessary yk rmq::segtree* tmp = new rmq::segtree(0, n - 1); vector<rmq::segtree*> ac(m, 0); for (int i = m - 1; i >= 0; i--) { ac[i] = tmp = tmp->upd(a[i], i); } rsq::segtree* tmp2 = new rsq::segtree(0, m - 1); vector<rsq::segtree*> ac2(n + 1, 0); for (int i = 0; i <= n; i++) { for (auto& x : a2[i]) tmp2 = tmp2->upd(x, i + 1); ac2[i] = tmp2; } rsq::segtree* tmp3 = new rsq::segtree(0, m - 1); vector<rsq::segtree*> ac3(n + 1, 0); for (int i = n; i >= 0; i--) { for (auto& x : a2[i]) { tmp3 = tmp3->upd(x, n - 1 - i); } ac3[i] = tmp3; } bit die(n + 1); for (int i = 0; i <= n; i++) die.u(i, i, i); die.us.clear(); for (int j = 0; j + magic <= m; j += magic) { int k = j / magic; for (int x = j; x < j + magic; x++) { int cur = 0; while (cur <= n) { int i = die.q(cur) / (n + 1); int l = cur - 1, r = n + 1; while (r - l > 1) { int m = l + (r - l) / 2; if (die.q(m) / (n + 1) == i) l = m; else r = m; } //[cur, l] is bound int l2 = cur - 1, r2 = l + 1; while (r2 - l2 > 1) { int m = l2 + (r2 - l2) / 2; if (die.q(m) % (n + 1) <= a[x]) l2 = m; else r2 = m; } //r is bound die.u(cur, l2, 1); cur = l + 1; } die.u(0, n, a[x] + 1); } int ps = 0; for (int i = 0; i <= n; i++) { ps += die.a[i]; holy[k][i] = ps % (n + 1); } for (auto& x : die.us)die.u(x.first, -x.second); die.us.clear(); } int q; cin >> q; while (q--) { int l, r; cin >> l >> r; l--;r--; //solve int li = -1, ri = n; int cur = l; auto qcnt = [&](int l, int r) { int res = 0; if (l > r) return 0LL; if (r <= li) return r - l + 1; if (l >= ri) return 0LL; if (l <= li) { res += li - l + 1; l = li + 1; } if (r >= ri) r = ri - 1; return res + sm(l, r); //LMAO }; auto qcnt2 = [&](int l, int r) { if (l > r) return 0LL; return (r - l + 1) - qcnt(l, r);}; auto thing = [&](int t) { // should work for everything? int a = qcnt(0, t - 1) * 2 + 1; int b = qcnt2(t + 1, n - 1) * 2; if (a > b) { int ll = 0 - 1, rr = t + 1; while (rr - ll > 1) { int m = ll + (rr - ll) / 2; if (qcnt(m, t - 1) * 2 + 1 >= b)ll = m; else rr = m; } ri = min(ri, ll); if (li >= ri) li = ri - 1; } else { int ll = t, rr = n; while (rr - ll > 1) { int m = ll + (rr - ll) / 2; if (qcnt2(t + 1, m) * 2 >= a)rr = m; else ll = m; } li = rr; if (ri <= li) ri = li + 1; } }; auto test = [&](int t) -> bool { int v1 = li == -1 ? 0 : ac2[li]->q(cur, t); int v2 = ri == n ? 0 : ac3[ri]->q(cur, t); int tmp1 = prev(upper_bound(ls.begin(), ls.end(), li)) - ls.begin(); int tmp2 = prev(upper_bound(rs.begin(), rs.end(), ri, greater<int>())) - rs.begin(); if (tmp1 + v1 >= ls.size()) return false; if (tmp2 + v2 >= rs.size()) return false; int nl = v1 ? ls[tmp1 + v1] : li; int nr = v2 ? rs[tmp2 + v2] : ri; if (nl >= nr) return false; li = nl; ri = nr; cur = t + 1; return true; }; while (cur <= r) { int t = min(ac[cur]->q(li + 1, ri - 1), r + 1); //do the thing? if (!test(t - 1)) break; if (cur <= r)thing(a[cur++]); } if (cur <= r && li + 1 != ri) { int t = min(ac[cur]->q(li + 1, ri - 1), r + 1); for (int i = 18; i >= 0; i--) { if (cur + (1 << i) <= t - 1) test(cur + (1 << i)); } } for (int i = 0; i < 2; i++) if (cur <= r) thing(a[cur++]); int nxt = (cur / magic + 1) * magic; while (cur <= r) { if (cur == nxt && cur + magic <= r + 1) { ri = holy[cur / magic][ri]; li = ri - 1; cur += magic; nxt += magic; } else { if (a[cur] >= ri) ri++; ri += a[cur] + 1; while (ri >= n + 1) ri -= (n + 1); li = ri - 1; cur++; } } cout << qcnt(0, n - 1) << endl; } }

Compilation message (stderr)

Main.cpp: In member function 'void bit::u(long long int, long long int)':
Main.cpp:77:57: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::vector<long long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   77 |     void u(int i, int v) { us.push_back({ i, v });if (i < a.size()) a[i] += v; for (i++; i < b.size(); i += i & -i) b[i] += v; }
      |                                                       ~~^~~~~~~~~~
Main.cpp:77:92: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::vector<long long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   77 |     void u(int i, int v) { us.push_back({ i, v });if (i < a.size()) a[i] += v; for (i++; i < b.size(); i += i & -i) b[i] += v; }
      |                                                                                          ~~^~~~~~~~~~
Main.cpp: In lambda function:
Main.cpp:224:27: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::vector<long long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  224 |             if (tmp1 + v1 >= ls.size()) return false;
      |                 ~~~~~~~~~~^~~~~~~~~~~~
Main.cpp:225:27: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::vector<long long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  225 |             if (tmp2 + v2 >= rs.size()) return false;
      |                 ~~~~~~~~~~^~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...