답안 #950552

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
950552 2024-03-20T12:26:02 Z peterandvoi Modern Machine (JOI23_ho_t5) C++17
62 / 100
3000 ms 239880 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 = 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:137:34: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
  137 |                     int mid = tl + tr >> 1;
      |                               ~~~^~~~
# 결과 실행 시간 메모리 Grader output
1 Correct 58 ms 165712 KB Output is correct
2 Correct 20 ms 165724 KB Output is correct
3 Correct 20 ms 165724 KB Output is correct
4 Correct 23 ms 166312 KB Output is correct
5 Correct 22 ms 165724 KB Output is correct
6 Correct 19 ms 165720 KB Output is correct
7 Correct 21 ms 165724 KB Output is correct
8 Correct 20 ms 165676 KB Output is correct
9 Correct 23 ms 165724 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 58 ms 165712 KB Output is correct
2 Correct 20 ms 165724 KB Output is correct
3 Correct 20 ms 165724 KB Output is correct
4 Correct 23 ms 166312 KB Output is correct
5 Correct 22 ms 165724 KB Output is correct
6 Correct 19 ms 165720 KB Output is correct
7 Correct 21 ms 165724 KB Output is correct
8 Correct 20 ms 165676 KB Output is correct
9 Correct 23 ms 165724 KB Output is correct
10 Correct 32 ms 168272 KB Output is correct
11 Correct 37 ms 169112 KB Output is correct
12 Correct 39 ms 169292 KB Output is correct
13 Correct 26 ms 167260 KB Output is correct
14 Correct 30 ms 169024 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 58 ms 165712 KB Output is correct
2 Correct 20 ms 165724 KB Output is correct
3 Correct 20 ms 165724 KB Output is correct
4 Correct 23 ms 166312 KB Output is correct
5 Correct 22 ms 165724 KB Output is correct
6 Correct 19 ms 165720 KB Output is correct
7 Correct 21 ms 165724 KB Output is correct
8 Correct 20 ms 165676 KB Output is correct
9 Correct 23 ms 165724 KB Output is correct
10 Correct 32 ms 168272 KB Output is correct
11 Correct 37 ms 169112 KB Output is correct
12 Correct 39 ms 169292 KB Output is correct
13 Correct 26 ms 167260 KB Output is correct
14 Correct 30 ms 169024 KB Output is correct
15 Correct 20 ms 165724 KB Output is correct
16 Correct 20 ms 165724 KB Output is correct
17 Correct 20 ms 165720 KB Output is correct
18 Correct 338 ms 207852 KB Output is correct
19 Correct 349 ms 219400 KB Output is correct
20 Correct 390 ms 236100 KB Output is correct
21 Correct 356 ms 236588 KB Output is correct
22 Correct 376 ms 229264 KB Output is correct
23 Correct 217 ms 222612 KB Output is correct
24 Correct 225 ms 230152 KB Output is correct
25 Correct 214 ms 230148 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 20 ms 165720 KB Output is correct
2 Correct 317 ms 199508 KB Output is correct
3 Correct 369 ms 199500 KB Output is correct
4 Correct 1853 ms 190856 KB Output is correct
5 Correct 243 ms 199332 KB Output is correct
6 Correct 243 ms 199312 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 20 ms 165720 KB Output is correct
2 Correct 317 ms 199508 KB Output is correct
3 Correct 369 ms 199500 KB Output is correct
4 Correct 1853 ms 190856 KB Output is correct
5 Correct 243 ms 199332 KB Output is correct
6 Correct 243 ms 199312 KB Output is correct
7 Correct 22 ms 165720 KB Output is correct
8 Correct 20 ms 165712 KB Output is correct
9 Correct 21 ms 165632 KB Output is correct
10 Correct 28 ms 167516 KB Output is correct
11 Correct 848 ms 239624 KB Output is correct
12 Correct 985 ms 239880 KB Output is correct
13 Correct 409 ms 239108 KB Output is correct
14 Correct 475 ms 239684 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 20 ms 165720 KB Output is correct
2 Correct 317 ms 199508 KB Output is correct
3 Correct 369 ms 199500 KB Output is correct
4 Correct 1853 ms 190856 KB Output is correct
5 Correct 243 ms 199332 KB Output is correct
6 Correct 243 ms 199312 KB Output is correct
7 Correct 21 ms 165724 KB Output is correct
8 Correct 22 ms 165712 KB Output is correct
9 Correct 21 ms 165588 KB Output is correct
10 Correct 19 ms 165724 KB Output is correct
11 Correct 21 ms 165724 KB Output is correct
12 Correct 19 ms 165716 KB Output is correct
13 Correct 19 ms 165724 KB Output is correct
14 Correct 20 ms 165692 KB Output is correct
15 Correct 23 ms 165724 KB Output is correct
16 Correct 20 ms 165608 KB Output is correct
17 Correct 32 ms 168224 KB Output is correct
18 Correct 328 ms 208516 KB Output is correct
19 Correct 534 ms 211008 KB Output is correct
20 Correct 713 ms 212744 KB Output is correct
21 Correct 730 ms 216672 KB Output is correct
22 Correct 791 ms 220792 KB Output is correct
23 Correct 773 ms 221024 KB Output is correct
24 Execution timed out 3071 ms 205404 KB Time limit exceeded
25 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 58 ms 165712 KB Output is correct
2 Correct 20 ms 165724 KB Output is correct
3 Correct 20 ms 165724 KB Output is correct
4 Correct 23 ms 166312 KB Output is correct
5 Correct 22 ms 165724 KB Output is correct
6 Correct 19 ms 165720 KB Output is correct
7 Correct 21 ms 165724 KB Output is correct
8 Correct 20 ms 165676 KB Output is correct
9 Correct 23 ms 165724 KB Output is correct
10 Correct 32 ms 168272 KB Output is correct
11 Correct 37 ms 169112 KB Output is correct
12 Correct 39 ms 169292 KB Output is correct
13 Correct 26 ms 167260 KB Output is correct
14 Correct 30 ms 169024 KB Output is correct
15 Correct 20 ms 165724 KB Output is correct
16 Correct 20 ms 165724 KB Output is correct
17 Correct 20 ms 165720 KB Output is correct
18 Correct 338 ms 207852 KB Output is correct
19 Correct 349 ms 219400 KB Output is correct
20 Correct 390 ms 236100 KB Output is correct
21 Correct 356 ms 236588 KB Output is correct
22 Correct 376 ms 229264 KB Output is correct
23 Correct 217 ms 222612 KB Output is correct
24 Correct 225 ms 230152 KB Output is correct
25 Correct 214 ms 230148 KB Output is correct
26 Correct 20 ms 165720 KB Output is correct
27 Correct 317 ms 199508 KB Output is correct
28 Correct 369 ms 199500 KB Output is correct
29 Correct 1853 ms 190856 KB Output is correct
30 Correct 243 ms 199332 KB Output is correct
31 Correct 243 ms 199312 KB Output is correct
32 Correct 22 ms 165720 KB Output is correct
33 Correct 20 ms 165712 KB Output is correct
34 Correct 21 ms 165632 KB Output is correct
35 Correct 28 ms 167516 KB Output is correct
36 Correct 848 ms 239624 KB Output is correct
37 Correct 985 ms 239880 KB Output is correct
38 Correct 409 ms 239108 KB Output is correct
39 Correct 475 ms 239684 KB Output is correct
40 Correct 21 ms 165724 KB Output is correct
41 Correct 22 ms 165712 KB Output is correct
42 Correct 21 ms 165588 KB Output is correct
43 Correct 19 ms 165724 KB Output is correct
44 Correct 21 ms 165724 KB Output is correct
45 Correct 19 ms 165716 KB Output is correct
46 Correct 19 ms 165724 KB Output is correct
47 Correct 20 ms 165692 KB Output is correct
48 Correct 23 ms 165724 KB Output is correct
49 Correct 20 ms 165608 KB Output is correct
50 Correct 32 ms 168224 KB Output is correct
51 Correct 328 ms 208516 KB Output is correct
52 Correct 534 ms 211008 KB Output is correct
53 Correct 713 ms 212744 KB Output is correct
54 Correct 730 ms 216672 KB Output is correct
55 Correct 791 ms 220792 KB Output is correct
56 Correct 773 ms 221024 KB Output is correct
57 Execution timed out 3071 ms 205404 KB Time limit exceeded
58 Halted 0 ms 0 KB -