B. 攻防演练 (倍增)
攻防演练
来源
2021年中国大学生程序设计竞赛女生专场
https://codeforces.com/gym/103389/problem/B
题解
注意倍增的递推顺序还有 \(0,n+1\) 的情况!!!
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 5, K = 20, M = 30;
int m, n, q, l, r;
string s;
int nxt[N], pos[M];
int f[N][K]; //f[i][j]: i开始,跳2^j步到的点
int main () {
ios::sync_with_stdio (0);cin.tie(0);cout.tie (0);
cin >> m >> n >> s >> q;
s = ' ' + s;
for (int i = 0; i < m; i++) pos[i] = n + 1;
for (int i = n; i >= 0; i--) {
for (int j = 0; j < m; j++) {
f[i][0] = max (f[i][0], pos[j]);
}
pos[s[i] - 'a'] = i;
}
// cout << endl;
f[n + 1][0] = n + 1;
for (int i = n + 1; i >= 0; i--) {
// cout << f[i][0] << ' ';
for (int j = 1; (1 << j) <= n; j++) {
f[i][j] = f[f[i][j-1]][j-1];
// cout << f[i][j] << ' ';
}
// cout << endl;
}
while (q--) {
cin >> l >> r;
//L-1开始跳
l--;
int ans = 1;
for (int i = log2 (n); i >= 0; i--) {
if (f[l][i] <= r) {
ans += (1 << i);
l = f[l][i];
}
}
cout << ans << "\n";
}
//cout << log2 (2e5) << ' ' << logn;
}