답안 #950548

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
950548 2024-03-20T12:15:47 Z peterandvoi Modern Machine (JOI23_ho_t5) C++17
25 / 100
1732 ms 236584 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;
    while (true) {
        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 = nxt - 2;
                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:137:34: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
  137 |                     int mid = tl + tr >> 1;
      |                               ~~~^~~~
# 결과 실행 시간 메모리 Grader output
1 Correct 25 ms 165716 KB Output is correct
2 Correct 20 ms 165732 KB Output is correct
3 Correct 19 ms 165724 KB Output is correct
4 Correct 19 ms 165724 KB Output is correct
5 Correct 19 ms 165812 KB Output is correct
6 Correct 19 ms 165720 KB Output is correct
7 Correct 19 ms 165816 KB Output is correct
8 Correct 19 ms 165692 KB Output is correct
9 Correct 19 ms 165724 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 25 ms 165716 KB Output is correct
2 Correct 20 ms 165732 KB Output is correct
3 Correct 19 ms 165724 KB Output is correct
4 Correct 19 ms 165724 KB Output is correct
5 Correct 19 ms 165812 KB Output is correct
6 Correct 19 ms 165720 KB Output is correct
7 Correct 19 ms 165816 KB Output is correct
8 Correct 19 ms 165692 KB Output is correct
9 Correct 19 ms 165724 KB Output is correct
10 Correct 34 ms 168212 KB Output is correct
11 Correct 40 ms 169044 KB Output is correct
12 Correct 35 ms 169304 KB Output is correct
13 Correct 26 ms 167252 KB Output is correct
14 Correct 29 ms 169020 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 25 ms 165716 KB Output is correct
2 Correct 20 ms 165732 KB Output is correct
3 Correct 19 ms 165724 KB Output is correct
4 Correct 19 ms 165724 KB Output is correct
5 Correct 19 ms 165812 KB Output is correct
6 Correct 19 ms 165720 KB Output is correct
7 Correct 19 ms 165816 KB Output is correct
8 Correct 19 ms 165692 KB Output is correct
9 Correct 19 ms 165724 KB Output is correct
10 Correct 34 ms 168212 KB Output is correct
11 Correct 40 ms 169044 KB Output is correct
12 Correct 35 ms 169304 KB Output is correct
13 Correct 26 ms 167252 KB Output is correct
14 Correct 29 ms 169020 KB Output is correct
15 Correct 20 ms 165792 KB Output is correct
16 Correct 19 ms 165720 KB Output is correct
17 Correct 19 ms 165724 KB Output is correct
18 Correct 324 ms 207896 KB Output is correct
19 Correct 341 ms 219400 KB Output is correct
20 Correct 370 ms 236036 KB Output is correct
21 Correct 337 ms 236584 KB Output is correct
22 Correct 374 ms 229380 KB Output is correct
23 Correct 205 ms 223044 KB Output is correct
24 Correct 213 ms 230244 KB Output is correct
25 Correct 214 ms 230152 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 19 ms 165724 KB Output is correct
2 Correct 296 ms 199440 KB Output is correct
3 Correct 348 ms 199328 KB Output is correct
4 Correct 1732 ms 191740 KB Output is correct
5 Correct 255 ms 200832 KB Output is correct
6 Incorrect 241 ms 201148 KB Output isn't correct
7 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 19 ms 165724 KB Output is correct
2 Correct 296 ms 199440 KB Output is correct
3 Correct 348 ms 199328 KB Output is correct
4 Correct 1732 ms 191740 KB Output is correct
5 Correct 255 ms 200832 KB Output is correct
6 Incorrect 241 ms 201148 KB Output isn't correct
7 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 19 ms 165724 KB Output is correct
2 Correct 296 ms 199440 KB Output is correct
3 Correct 348 ms 199328 KB Output is correct
4 Correct 1732 ms 191740 KB Output is correct
5 Correct 255 ms 200832 KB Output is correct
6 Incorrect 241 ms 201148 KB Output isn't correct
7 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 25 ms 165716 KB Output is correct
2 Correct 20 ms 165732 KB Output is correct
3 Correct 19 ms 165724 KB Output is correct
4 Correct 19 ms 165724 KB Output is correct
5 Correct 19 ms 165812 KB Output is correct
6 Correct 19 ms 165720 KB Output is correct
7 Correct 19 ms 165816 KB Output is correct
8 Correct 19 ms 165692 KB Output is correct
9 Correct 19 ms 165724 KB Output is correct
10 Correct 34 ms 168212 KB Output is correct
11 Correct 40 ms 169044 KB Output is correct
12 Correct 35 ms 169304 KB Output is correct
13 Correct 26 ms 167252 KB Output is correct
14 Correct 29 ms 169020 KB Output is correct
15 Correct 20 ms 165792 KB Output is correct
16 Correct 19 ms 165720 KB Output is correct
17 Correct 19 ms 165724 KB Output is correct
18 Correct 324 ms 207896 KB Output is correct
19 Correct 341 ms 219400 KB Output is correct
20 Correct 370 ms 236036 KB Output is correct
21 Correct 337 ms 236584 KB Output is correct
22 Correct 374 ms 229380 KB Output is correct
23 Correct 205 ms 223044 KB Output is correct
24 Correct 213 ms 230244 KB Output is correct
25 Correct 214 ms 230152 KB Output is correct
26 Correct 19 ms 165724 KB Output is correct
27 Correct 296 ms 199440 KB Output is correct
28 Correct 348 ms 199328 KB Output is correct
29 Correct 1732 ms 191740 KB Output is correct
30 Correct 255 ms 200832 KB Output is correct
31 Incorrect 241 ms 201148 KB Output isn't correct
32 Halted 0 ms 0 KB -