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;
}

浙公网安备 33010602011771号