WA on #3 求调,问题很小
查看原帖
WA on #3 求调,问题很小
700558
williamwei楼主2024/4/3 22:11
#include <iostream>
#include <vector>
#include <algorithm>
#include <tuple>
using namespace std;
typedef long long ll;
const int maxn = 1e5 + 10;
const int inf = 0x3f3f3f3f;
const ll infll = 0x3f3f3f3f3f3f3f3f;
int n, d, m, q, rt, tot, sz[maxn], ls[maxn], rs[maxn], val[maxn];
ll a[maxn], c[maxn], A[maxn], res[maxn];
bool id[maxn], f[maxn];
char s[maxn];
void pushdown(int k) {
    if (A[k]) {
        c[ls[k]] += A[k]; A[ls[k]] += A[k];
        c[rs[k]] += A[k]; c[rs[k]] += A[k];
        A[k] = 0;
    }
}
void pushup(int k) {
    sz[k] = sz[ls[k]] + sz[rs[k]] + 1;
    f[k] = f[ls[k]] || f[rs[k]] || id[k];
}
void split(int k, int& l, int& r, int v) {
    if (!k) { l = r = 0; return; } pushdown(k);
    if (v <= sz[ls[k]]) r = k, split(ls[k], l, ls[k], v);
    else l = k, split(rs[k], rs[k], r, v - sz[ls[k]] - 1);
    pushup(k);
}
int merge(int l, int r) {
    pushdown(l); pushdown(r);
    if (!l || !r) return l | r; int k;
    if (val[l] < val[r]) k = l, rs[k] = merge(rs[k], r);
    else k = r, ls[k] = merge(l, ls[k]);
    pushup(k); return k;
}
ll query(int k) {
    int x, y; split(rt, x, y, k); int p = x;
    for (; rs[p]; p = rs[p]) pushdown(p);
    ll res = c[p]; rt = merge(x, y); return res;
}
int pre(int k) {
    if (!f[k]) return inf;
    if (!k) return 0;
    if (f[ls[k]]) return pre(ls[k]);
    else if (id[k]) return sz[ls[k]] + 1;
    return sz[ls[k]] + 1 + pre(rs[k]);
}
ll nxt(int x, int s) { --s; return query(s % x + 1) + (ll)(s / x + 1) * (d + x - 1); }
int main() {
    ios::sync_with_stdio(false);
    cin >> n >> d >> q;
    for (int i = 1; i <= n; i++) cin >> c[i];
    cin >> s + 1; srand(20101008);
    for (int i = 1; i <= n; i++)
        sz[i] = 1, val[i] = rand(),
        id[i] = f[i] = s[i] == '0', rt = merge(rt, i);
    vector<tuple<int, int, int> > g(q);
    for (auto& [x, y, id] : g) cin >> x >> y, id = ++m;
    sort(g.begin(), g.end());
    for (int cur = 0, v = 0; cur < m;) {
        int p = pre(rt);
        if (p == 1) {
            int x; split(rt, x, rt, 1);
            a[++tot] = c[x]; continue;
        }
        int l = 1, r = sz[rt], x = 0;
        for (ll k = query(1); l <= r; ) {
            int mid = l + ((r - l) >> 1);
            if (query(mid) < k + d + mid - 1) l = mid + 1, x = mid;
            else r = mid - 1;
        }
        ll k = x == sz[rt] ? infll : query(x + 1);
        l = 1, r = p <= x ? p - 1 : inf;
        while (l <= r) {
            int mid = l + ((r - l) >> 1);
            if (nxt(x, mid) < k) l = mid + 1, p = mid;
            else r = mid - 1;
        }
        for (; cur < m; cur++) {
            auto [X, Y, id] = g[cur];
            if (X > v + p) break;
            if (Y <= tot) { res[id] = a[Y]; continue; }
            int K = Y - tot; if (K > x) { res[id] = query(K); continue; }
            int P = (K + X - v - 1) % x + 1;
            res[id] = query(P) + (ll)(d + x - 1) * ((X - v) / x + (P <= (X - v) % x));
        }
        int a1, a2, a3; split(rt, a1, a3, x); split(a1, a1, a2, p % x);
        c[a1] += (ll)(d + x - 1) * (p / x + 1); A[a1] += (ll)(d + x - 1) * (p / x + 1);
        c[a2] += (ll)(d + x - 1) * (p / x); A[a2] += (ll)(d + x - 1) * (p / x);
        rt = merge(merge(a2, a1), a3); v += p;
    }
    for (int i = 1; i <= m; i++) cout << res[i] << '\n';
    return 0;
}
2024/4/3 22:11
加载中...