Submission #1182628

#TimeUsernameProblemLanguageResultExecution timeMemory
1182628jerzykModern Machine (JOI23_ho_t5)C++20
25 / 100
3097 ms76828 KiB
#include <bits/stdc++.h> #pragma GCC target ("avx2") #pragma GCC optimization ("O3") #pragma GCC optimization ("unroll-loops") using namespace std; #define pb push_back #define st first #define nd second typedef long long ll; typedef long double ld; const ll I = 1000'000'000'000'000'000LL; const int II = 2'000'000'000; const ll M = 1000'000'007LL; const int N = 1<<17; string wzo; int s0[N], s1[N]; int tab[N]; ll il0[N], il1[N]; int mi[N][20], ma[N][20]; int r0[N], r1[N]; vector<pair<pair<int, int>, int>> drz[2 * N]; vector<int> wh[2]; int bs0[N], bs1[N]; inline void LiczBS(int n) { bs0[0] = 0; bs1[n + 1] = (int)wh[1].size() - 1; for(int i = 1; i <= n; ++i) { bs0[i] = bs0[i - 1]; while(bs0[i] < (int)wh[0].size() - 1 && wh[0][bs0[i] + 1] <= i) ++bs0[i]; } for(int i = n; i >= 1; --i) { bs1[i] = bs1[i + 1]; while(bs1[i] > 0 && wh[1][bs1[i] - 1] >= i) --bs1[i]; } } inline void LiczR(int n) { for(int i = 1; i <= n + 1; ++i) { r1[i] = i; if(wzo[i - 1] == '<') r1[i] = r1[i - 1]; } r0[n] = n; for(int i = n - 1; i >= 0; --i) { r0[i] = i; if(wzo[i + 1] == '>') r0[i] = r0[i + 1]; } } inline void LiczRMQ(int n) { for(int i = n; i >= 1; --i) for(int j = 1; i + (1<<j) - 1 <= n; ++j) { mi[i][j] = min(mi[i][j - 1], mi[i + (1<<(j - 1))][j - 1]); ma[i][j] = max(ma[i][j - 1], ma[i + (1<<(j - 1))][j - 1]); } } inline int MiQ(int a, int b) { int d = (b - a + 1); int j = 31 - __builtin_clz(d); return min(mi[a][j], mi[b - (1<<j) + 1][j]); } int MaQ(int a, int b) { int d = (b - a + 1); int j = 31 - __builtin_clz(d); return max(ma[a][j], ma[b - (1<<j) + 1][j]); } inline bool Int(pair<int, int> a, pair<int, int> b) { return (max(a.st, b.st) <= min(a.nd, b.nd)); } inline pair<int, int> GInt(pair<int, int> a, pair<int, int> b) { return make_pair(max(a.st, b.st), min(a.nd, b.nd)); } inline void Calc(int v, int n) { int s1 = v * 2, s2 = v * 2 + 1; ++n; if(drz[s1].size() == 0 || drz[s2].size() == 0) return; //cerr << "CalcB " << s1 - N << " " << s2 - N << "\n"; vector<pair<pair<int, int>, int>> akt; int m = drz[s2].size(); int j = 0; for(int i = 0; i < (int)drz[s1].size(); ++i) { int l = (drz[s1][i].st.st + drz[s1][i].nd) % n, r = (drz[s1][i].st.nd + drz[s1][i].nd) % n; vector<pair<int, int>> nw; if(l <= r) nw.pb(make_pair(l, r)); else { nw.pb(make_pair(l, n - 1)); nw.pb(make_pair(0, r)); } for(int l = 0; l < (int)nw.size(); ++l) { //if(nw[l].st < drz[s2][j].st.st) j = 0; //cout << "\n" << i << " " << "NW: " << nw[l].st << " " << nw[l].nd << "\n"; while(!Int(nw[l], drz[s2][j].st) || GInt(nw[l], drz[s2][j].st).st != nw[l].st) { //cerr << nw[l].st << " " << nw[l].nd << "XD\n"; j = (j + 1) % m; } while(j < m && Int(nw[l], drz[s2][j].st)) { pair<int, int> it = GInt(nw[l], drz[s2][j].st); //cerr << j << " IT: " << it.st << " " << it.nd << "\n"; it.st = (it.st - drz[s1][i].nd + n) % n; it.nd = (it.nd - drz[s1][i].nd + n) % n; akt.pb(make_pair(it, (drz[s1][i].nd + drz[s2][j].nd) % n)); ++j; } j = (j - 1 + m) % m; } } if((int)akt.size() > 0) drz[v].pb(akt[0]); for(int i = 1; i < (int)akt.size(); ++i) { if(akt[i].nd == drz[v].back().nd) drz[v].back().st.nd = akt[i].st.nd; else drz[v].pb(akt[i]); } //if(drz[v].back().st.nd != n - 1) //cout << drz[v].back().st.nd << " " << "Dupa XD\n"; //for(int i = 0; i < (int)drz[v].size(); ++i) //cout << "R: " << drz[v][i].st.st << " " << drz[v][i].st.nd << " " << drz[v][i].nd << "\n"; //cout << "CalcE\n"; } inline int F(int v, int x) { int pos = (upper_bound(drz[v].begin(), drz[v].end(), make_pair(make_pair(x + 1, 0), 0)) - drz[v].begin()) - 1; x += drz[v][pos].nd; return x; } inline int Query(int a, int b, int bas, int n) { a += N - 1; b += N + 1; vector<int> q; while(a / 2 != b / 2) { if(a % 2 == 0) bas = F(a + 1, bas) % (n + 1); if(b % 2 == 1) q.pb(b - 1); a /= 2; b /= 2; } for(int i = (int)q.size() - 1; i >= 0; --i) bas = F(q[i], bas) % (n + 1); return bas; } inline bool Check(int a, int x, int l, int r, int p0, int p1) { if(MiQ(a, x) < r) return 0; if(MaQ(a, x) > l) return 0; ll d0 = il0[x] - il0[a - 1]; ll d1 = il1[x] - il1[a - 1]; if((ll)p0 + (ll)d0 >= (int)wh[0].size()) return 0; if((ll)p1 - (ll)d1 < 0) return 0; if(max(l, wh[0][p0 + d0]) >= min(r, wh[1][p1 - d1])) return 0; return 1; } inline void Upd(int a, int x, int &l, int &r, int &p0, int &p1) { ll d0 = il0[x] - il0[a - 1]; ll d1 = il1[x] - il1[a - 1]; p0 += d0; p1 -= d1; l = wh[0][p0]; r = wh[1][p1]; } inline void Manual(int n, int pos, int &l, int &r, int &p0, int &p1) { int lew = 0, pr = 0; if(pos <= l) lew = pos - 1; else lew = l + s1[min(pos, r) - 1] - s1[l]; if(pos >= r) pr = n - pos; else pr = n - r + 1 + s0[r - 1] - s0[max(pos, l)]; //cout << l << " " << r << " " << pos << " " << "Q: " << lew << " " << pr << "\n"; if(lew < pr) { int del = lew + 1; int p2; int fr = 0; if(pos < r) fr = s0[r - 1] - s0[max(l, pos)]; if(fr >= del) { //p2 = (upper_bound(wh[0].begin(), wh[0].end(), max(l, pos)) - wh[0].begin()) + del - 1; p2 = (bs0[max(l, pos)] + 1) + del - 1; l = wh[0][p2]; }else { del -= fr; l = max(pos + 1, r) + del - 1; r = l + 1; } }else { int del = pr; int p2; int fr = 0; if(pos > l) fr = s1[min(pos, r) - 1] - s1[l]; if(fr >= del) { //p2 = (lower_bound(wh[1].begin(), wh[1].end(), min(r, pos)) - wh[1].begin()) - del; p2 = (bs1[min(r, pos)]) - del; //cout << "p2: " << wh[1][p2] << "\n"; r = min(wh[1][p2], pos); l = min(l, r - 1); }else { del -= fr; r = min(pos - 1, l) - del + 1; l = r - 1; } } p0 = bs0[l]; p1 = bs1[r]; //p0 = (upper_bound(wh[0].begin(), wh[0].end(), l) - wh[0].begin()) - 1; //p1 = (lower_bound(wh[1].begin(), wh[1].end(), r) - wh[1].begin()); //cout << l << " " << r << " " << wh[0][p0] << " " << wh[1][p1] << "\n"; } inline int BS(int a, int b, int l, int r, int p0, int p1) { int p = a - 1, k = b, s; while(p < k) { s = (p + k + 1) / 2; if(Check(a, s, l, r, p0, p1)) p = s; else k = s - 1; } return p; } inline void Rozszerz(int &l, int &r, int &p0, int &p1) { l = min(r - 1, r0[l]); r = max(l + 1, r1[r]); } inline int DoA(int n, int a, int b) { int l = 0, r = n + 1; int p0 = 0, p1 = (int)wh[1].size() - 1; while(a <= b) { Rozszerz(l, r, p0, p1); int nxt = BS(a, b, l, r, p0, p1); //cout << a << " " << b << " " << nxt << "\n"; //cout << "B: " << l << " " << r << " " << p0 << " " << p1 << "\n"; Upd(a, nxt, l, r, p0, p1); Rozszerz(l, r, p0, p1); //cout << "A: " << l << " " << r << " " << p0 << " " << p1 << "\n"; a = nxt + 1; if(a <= b) { Manual(n, tab[a], l, r, p0, p1); ++a; } if(a <= b && l == r - 1) { return Query(a, b, l, n); } Rozszerz(l, r, p0, p1); } return l + s1[r - 1] - s1[l]; } void Solve() { int n, m, q; cin >> n >> m; cin >> wzo; wzo = '#' + wzo; LiczR(n); wh[0].pb(0); for(int i = 1; i <= n; ++i) { if(wzo[i] == 'B') { ++s0[i]; wh[0].pb(i); } else { ++s1[i]; wh[1].pb(i); } s0[i] += s0[i - 1]; s1[i] += s1[i - 1]; } s0[n + 1] += s0[n]; s1[n + 1] += s1[n]; wh[1].pb(n + 1); for(int i = 1; i <= m; ++i) { cin >> tab[i]; mi[i][0] = II; ma[i][0] = 0; if(tab[i] <= (n / 2)) { ma[i][0] = tab[i]; il0[i] += tab[i]; } else { mi[i][0] = tab[i]; il1[i] += (n - tab[i]); } il0[i] += il0[i - 1]; il1[i] += il1[i - 1]; drz[i + N].pb(make_pair(make_pair(0, tab[i] - 1), tab[i] + 1)); drz[i + N].pb(make_pair(make_pair(tab[i], n), tab[i])); } LiczBS(n); LiczRMQ(n); for(int i = N - 1; i >= 1; --i) Calc(i, n); cin >> q; for(int i = 1; i <= q; ++i) { int a, b; cin >> a >> b; int ans = DoA(n, a, b); //int ans = Query(a, b, bas, n); cout << ans << "\n"; } } int main() { ios_base::sync_with_stdio(false); cin.tie(nullptr); //int t; cin >> t; //while(t--) Solve(); return 0; }
#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...