답안 #950553

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
950553 2024-03-20T12:28:06 Z peterandvoi Modern Machine (JOI23_ho_t5) C++17
25 / 100
381 ms 385424 KB
#include <bits/stdc++.h>

using namespace std;

#ifdef ngu
#include "debug.h"
#else
#define debug(...) 42
#endif

const int N = 120005;

int n, m, q;
char c[N];
int a[N];

struct from_to {
    int l, L, len;

    from_to(): l(0), L(0), len(0) {};

    from_to(int l, int L, int len): l(l), L(L), len(len) {};

    int r() const {
        return l + len - 1;
    }

    bool operator < (const from_to &oth) const {
        return l < oth.l;
    }
};

int add(int a, int b) {
    a += b;
    while (a >= n + 1) {
        a -= n + 1;
    }
    return a;
}

vector<from_to> tree[N << 2];

vector<from_to> cmb(const vector<from_to> &a, const vector<from_to> &b) {
    vector<from_to> res;
    for (auto [bl, al, len] : a) {
        int ar = add(al, len - 1);
        int br = add(bl, len - 1);
        int L = lower_bound(b.begin(), b.end(), from_to(al + 1, 0, 0)) - b.begin() - 1;
        int R = lower_bound(b.begin(), b.end(), from_to(ar + 1, 0, 0)) - b.begin() - 1;
        R += al > ar ? (int) b.size() : 0;
        for (int i = L; i <= R; ++i) {
            int j = i % (int) b.size();
            int delta = max(b[j].l, al) - b[j].l;
            int len = min(br - bl + 1, b[j].r() - max(b[j].l, al) + 1);
            int tl = add(b[j].L, delta);
            res.emplace_back(bl, tl, len);
            bl += len;
            al = add(al, len);
        }
    }
    return res;
}

void bld(int id, int l, int r) {
    if (l == r) {
        tree[id].emplace_back(0, add(0, a[l] + 1), a[l]);
        tree[id].emplace_back(a[l], add(a[l], a[l]), n - a[l] + 1);
    } else {
        int mid = l + r >> 1;
        bld(id << 1, l, mid);
        bld(id << 1 | 1, mid + 1, r);
        tree[id] = cmb(tree[id << 1], tree[id << 1 | 1]);
    }
}

int get(const vector<from_to> &a, int p) {
    int pos = lower_bound(a.begin(), a.end(), from_to(p + 1, 0, 0)) - a.begin() - 1;
    return add(a[pos].L, p - a[pos].l);
}

int qry(int u, int v, int p, int id = 1, int l = 1, int r = m) {
    if (u <= l && r <= v) {
        return get(tree[id], p);
    }
    int mid = l + r >> 1;
    if (u <= mid && mid < v) {
        return qry(u, v, qry(u, v, p, id << 1, l, mid), id << 1 | 1, mid + 1, r);
    }
    if (mid < u) {
        return qry(u, v, p, id << 1 | 1, mid + 1, r);
    }
    return qry(u, v, p, id << 1, l, mid);
}

const int LOG = 18;

int numB, numR;
int cnt_red[N];
int MASK[LOG];
int red[N], blue[N];
int jump[LOG][LOG][N];
int pushB[LOG][N], pushR[LOG][N];

int get(int l, int r, int pref[N]) {
    return pref[r] - pref[l - 1];
}

bool ck(int l, int r, int pos) {
    return red[r] <= pos || (blue[l] < pos && c[pos] == 'B');
}

int get_red(int l, int r, int pos) {
    int cnt = blue[l] + get(blue[l], red[r] - 1, cnt_red);
    if (pos != -1) {
        cnt = add(cnt, pos + ck(l, r, pos));
    }
    return cnt;
}

int qry(int l, int r) {
    int L = 0, R = 0, x = 0, y = 0;
    int iter = 2 * LOG;
    while (iter--) {
        int nxt = min(r + 1, jump[x][y][l]);
        if (l < nxt) {
            auto check = [&](int mid) {
                int tL = min(numB + 1, L + get(l, mid, pushB[x]));
                int tR = min(numR + 1, R + get(l, mid, pushR[y]));
                return blue[tL] < red[tR];
            };
            if (check(nxt - 1)) {
                L += get(l, nxt - 1, pushB[x]);
                R += get(l, nxt - 1, pushR[y]);
                l = nxt;
            } else {
                int tl = l, tr = nxt - 2, p = l - 1;
                while (tl <= tr) {
                    int mid = tl + tr >> 1;
                    if (check(mid)) {
                        p = mid;
                        tl = mid + 1;
                    } else {
                        tr = mid - 1;
                    }
                }
                L += get(l, p, pushB[x]);
                R += get(l, p, pushR[y]);
                int cnt = get_red(L, R, a[p + 1]);
                return p + 2 > r ? cnt : qry(p + 2, r, cnt);
            }
        }
        int num_red = get_red(L, R, -1);
        if (l == r + 1) {
            return num_red;
        }
        bool spec = ck(L, R, a[l]);
        int tl = L, tr = R;
        if (a[l] <= n - num_red) {
            tl = min(numB + 1, L + a[l] + spec);
        } else {
            tr = min(numR + 1, R + n - a[l] + !spec);
        }
        if (blue[tl] + 1 >= red[tr]) {
            int cnt = get_red(L, R, a[l]);
            return l + 1 > r ? cnt : qry(l + 1, r, cnt);
        }
        L = tl;
        R = tr;
        l++;
        while (x + 1 < LOG && MASK[x + 1] < blue[L]) {
            x++;
        }
        while (y + 1 < LOG && red[R] <= n - MASK[y + 1]) {
            y++;
        }
    }
    assert(0);
    return -1;
}

signed main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    #ifdef ngu
    freopen("test.inp", "r", stdin);
    freopen("test.out", "w", stdout);
    #endif
    cin >> n >> m;
    for (int i = 1; i < LOG; ++i) {
        MASK[i] = 1 << (i - 1);
    }
    for (int i = 1; i <= n; ++i) {
        cin >> c[i];
        cnt_red[i] = cnt_red[i - 1] + (c[i] == 'R');
        if (c[i] == 'B') {
            blue[++numB] = i;
        }
    }
    cnt_red[n + 1] = cnt_red[n];
    blue[numB + 1] = n + 1;
    red[0] = n + 1;
    for (int i = n; i >= 1; --i) {
        if (c[i] == 'R') {
            red[++numR] = i;
        }
    }
    for (int i = 1; i <= m; ++i) {
        cin >> a[i];
    }
    bld(1, 1, m);
    cin >> q;
    for (int i = 0; i < LOG; ++i) {
        for (int j = 0; j < LOG; ++j) {
            jump[i][j][m + 1] = m + 1;;
            for (int k = m; k >= 1; --k) {
                bool edge_case = a[k] == n && c[n] == 'B';
                jump[i][j][k] = MASK[i] < a[k] && a[k] <= n - MASK[j] && !edge_case ? k : jump[i][j][k + 1];
            }
        }
    }
    for (int i = 0; i < LOG; ++i) {
        for (int j = 1; j <= m; ++j) {
            pushB[i][j] = pushB[i][j - 1];
            pushR[i][j] = pushR[i][j - 1];
            if (a[j] <= MASK[i]) {
                pushB[i][j] += a[j];
            }
            if (n - MASK[i] < a[j]) {
                pushR[i][j] += n - a[j];
            }
        }
    }
    while (q--) {
        int l, r;
        cin >> l >> r;
        cout << qry(l, r) << "\n";
    }
}

Compilation message

Main.cpp: In function 'void bld(int, int, int)':
Main.cpp:69:21: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   69 |         int mid = l + r >> 1;
      |                   ~~^~~
Main.cpp: In function 'int qry(int, int, int, int, int, int)':
Main.cpp:85:17: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   85 |     int mid = l + r >> 1;
      |               ~~^~~
Main.cpp: In function 'int qry(int, int)':
Main.cpp:138:34: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
  138 |                     int mid = tl + tr >> 1;
      |                               ~~~^~~~
# 결과 실행 시간 메모리 Grader output
1 Correct 50 ms 165712 KB Output is correct
2 Correct 19 ms 165596 KB Output is correct
3 Correct 19 ms 165720 KB Output is correct
4 Correct 22 ms 165720 KB Output is correct
5 Correct 20 ms 165724 KB Output is correct
6 Correct 19 ms 165720 KB Output is correct
7 Correct 20 ms 165720 KB Output is correct
8 Correct 20 ms 165748 KB Output is correct
9 Correct 20 ms 165724 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 50 ms 165712 KB Output is correct
2 Correct 19 ms 165596 KB Output is correct
3 Correct 19 ms 165720 KB Output is correct
4 Correct 22 ms 165720 KB Output is correct
5 Correct 20 ms 165724 KB Output is correct
6 Correct 19 ms 165720 KB Output is correct
7 Correct 20 ms 165720 KB Output is correct
8 Correct 20 ms 165748 KB Output is correct
9 Correct 20 ms 165724 KB Output is correct
10 Correct 38 ms 168192 KB Output is correct
11 Correct 36 ms 169040 KB Output is correct
12 Correct 44 ms 169300 KB Output is correct
13 Correct 26 ms 167252 KB Output is correct
14 Correct 30 ms 169040 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 50 ms 165712 KB Output is correct
2 Correct 19 ms 165596 KB Output is correct
3 Correct 19 ms 165720 KB Output is correct
4 Correct 22 ms 165720 KB Output is correct
5 Correct 20 ms 165724 KB Output is correct
6 Correct 19 ms 165720 KB Output is correct
7 Correct 20 ms 165720 KB Output is correct
8 Correct 20 ms 165748 KB Output is correct
9 Correct 20 ms 165724 KB Output is correct
10 Correct 38 ms 168192 KB Output is correct
11 Correct 36 ms 169040 KB Output is correct
12 Correct 44 ms 169300 KB Output is correct
13 Correct 26 ms 167252 KB Output is correct
14 Correct 30 ms 169040 KB Output is correct
15 Correct 24 ms 165724 KB Output is correct
16 Correct 21 ms 165736 KB Output is correct
17 Correct 19 ms 165724 KB Output is correct
18 Correct 328 ms 207932 KB Output is correct
19 Correct 368 ms 219220 KB Output is correct
20 Correct 381 ms 236404 KB Output is correct
21 Correct 344 ms 236552 KB Output is correct
22 Correct 381 ms 229488 KB Output is correct
23 Correct 207 ms 222608 KB Output is correct
24 Correct 221 ms 230028 KB Output is correct
25 Correct 237 ms 230060 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 20 ms 165720 KB Output is correct
2 Correct 361 ms 199348 KB Output is correct
3 Correct 362 ms 199504 KB Output is correct
4 Runtime error 289 ms 385424 KB Execution killed with signal 6
5 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 20 ms 165720 KB Output is correct
2 Correct 361 ms 199348 KB Output is correct
3 Correct 362 ms 199504 KB Output is correct
4 Runtime error 289 ms 385424 KB Execution killed with signal 6
5 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 20 ms 165720 KB Output is correct
2 Correct 361 ms 199348 KB Output is correct
3 Correct 362 ms 199504 KB Output is correct
4 Runtime error 289 ms 385424 KB Execution killed with signal 6
5 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 50 ms 165712 KB Output is correct
2 Correct 19 ms 165596 KB Output is correct
3 Correct 19 ms 165720 KB Output is correct
4 Correct 22 ms 165720 KB Output is correct
5 Correct 20 ms 165724 KB Output is correct
6 Correct 19 ms 165720 KB Output is correct
7 Correct 20 ms 165720 KB Output is correct
8 Correct 20 ms 165748 KB Output is correct
9 Correct 20 ms 165724 KB Output is correct
10 Correct 38 ms 168192 KB Output is correct
11 Correct 36 ms 169040 KB Output is correct
12 Correct 44 ms 169300 KB Output is correct
13 Correct 26 ms 167252 KB Output is correct
14 Correct 30 ms 169040 KB Output is correct
15 Correct 24 ms 165724 KB Output is correct
16 Correct 21 ms 165736 KB Output is correct
17 Correct 19 ms 165724 KB Output is correct
18 Correct 328 ms 207932 KB Output is correct
19 Correct 368 ms 219220 KB Output is correct
20 Correct 381 ms 236404 KB Output is correct
21 Correct 344 ms 236552 KB Output is correct
22 Correct 381 ms 229488 KB Output is correct
23 Correct 207 ms 222608 KB Output is correct
24 Correct 221 ms 230028 KB Output is correct
25 Correct 237 ms 230060 KB Output is correct
26 Correct 20 ms 165720 KB Output is correct
27 Correct 361 ms 199348 KB Output is correct
28 Correct 362 ms 199504 KB Output is correct
29 Runtime error 289 ms 385424 KB Execution killed with signal 6
30 Halted 0 ms 0 KB -