CF217E Alien DNA

从前往后不好维护,考虑从最后一个操作开始逆着做。
类似并查集,我们维护一个点对应 $S$ 中的位置。
使用树桩数组优化过程。具体的:BIT 初始赋为 $1$,每次在 BIT 上倍增来查询位置。
复杂度 $O(K\log K)$


#include<bits/stdc++.h>

using namespace std;

const int N = 3e6 + 500;
int n, M, k;
int c[N], f[N];
void add(int s, int x) {
    for(f[s] = x, M--; s <= k; s += s & -s) c[s]--;
}
int multiply(int x) {
    int t = 1 << 22, s = 0;
    for(; t; t >>= 1) {
        if(s + t <= k && c[s + t] < x) 
            x -= c[s += t];
    }
    return s + 1;
}

char S[N], *s = S, a[N];
int L[N], R[N];

int main() {
    cin >> S + 1;
    cin >> k >> n;
    for(int i = 0; i <= k; ++i) c[i] = i & -i;
    for(int i = 1; i <= n; ++i) cin >> L[n - i + 1] >> R[n - i + 1];
    M = k;
    for(int i = 1; i <= n; ++i) {
        for(int x = L[i] + 1, j = 1; j <= R[i] - L[i] + 1 && R[i] <= M; add(multiply(R[i] + 1), multiply(x)), x += 2, j++)
        if(x > R[i]) x = L[i];
    }
    for(int i = 1; i <= k; ++i) cout << (a[i] = f[i] ? a[f[i]] : *(++s));
    return 0;
}
posted @ 2023-11-03 19:16  Saka_Noa  阅读(15)  评论(0)    收藏  举报  来源