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;
}
posted @ 2023-08-20 10:41  Sakana~  阅读(30)  评论(0编辑  收藏  举报