Fork me on GitHub

滞留卡常题

#include <bits/stdc++.h>

using namespace std;

const int N = 2e5 + 10;
const int M = N << 2;

int n, cnt[27], a[N][27];
int tr[M][27], tag[M][27], pos[M][27];
int sum;
string str;

void pushup(int op, int u)
{
    tr[u][op] = max(tr[u << 1][op], tr[u << 1 | 1][op]);
    if(tr[u << 1][op] >= tr[u << 1 | 1][op]) pos[u][op] = pos[u << 1][op];
    else pos[u][op] = pos[u << 1 | 1][op];
}

void build(int op, int u, int l, int r)
{
    int mid = l + r >> 1;
    if(l == r)
    {
        tr[u][op] = a[mid][op];
        pos[u][op] = mid;
        return;
    }
    build(op, u << 1, l, mid);
    build(op, u << 1 | 1, mid + 1, r);
    pushup(op, u);
}

void modify(int op, int u, int L, int R, int c, int l, int r)
{
    if(L <= l && r <= R)
    {
        tr[u][op] += c;
        tag[u][op] += c;
        return;
    }
    if(tag[u][op])
    {
        tag[u << 1][op] += tag[u][op];
        tr[u << 1][op] += tag[u][op];
        tag[u << 1 | 1][op] += tag[u][op];
        tr[u << 1 | 1][op] += tag[u][op];
        tag[u][op] = 0;
    }
    int mid = l + r >> 1;
    if(L <= mid) modify(op, u << 1, L, R, c, l, mid);
    if(R > mid) modify(op, u << 1 | 1, L, R, c, mid + 1, r);
    pushup(op, u);
}

int ps;

int qmax(int op, int u, int L, int R, int l, int r)
{
    if(L <= l && r <= R)
    {
        ps = pos[u][op];
        return tr[u][op];
    }
    int mid = l + r >> 1;
    if(tag[u][op])
    {
        tag[u << 1][op] += tag[u][op];
        tr[u << 1][op] += tag[u][op];
        tag[u << 1 | 1][op] += tag[u][op];
        tr[u << 1 | 1][op] += tag[u][op];
        tag[u][op] = 0;
    }
    int ans = 0;
    if(R > mid) ans = max(ans, qmax(op, u << 1 | 1, L, R, mid + 1, r));
    if(L <= mid) ans = max(ans, qmax(op, u << 1, L, R, l, mid));
    return ans; 
}

void query()
{
    int ans = sum - n;
    int pt = 1;
    for(int i = 2 ; i <= 26 ; i ++ )
    {
        int max_ = qmax(i, 1, pt, n, 1, n);
        if(max_ <= 0) break;
        ans -= max_;
        pt = ps;
    }
    cout << ans << '\n';
}
int main() 
{
	freopen("lock.in", "r", stdin);
	freopen("lock.out", "w", stdout);
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int q, op;
    cin >> op >> q;
    cin >> str;
    n = str.size();
    str = ' ' + str;
    for (int i = n ; i >= 1 ; i -- )
    {
        cnt[str[i] - 'a' + 1]++;
        sum += str[i] - 'a' + 1;
        int nsum = 0;
        for (int j = 26 ; j >= 1 ; j -- )
        {
            nsum += cnt[j];
            a[i][j] = nsum - (n - i + 1 - nsum);
        }
    }
    for (int i = 1; i <= 26; i++) build(i, 1, 1, n);
    query();
    while (q--) {
        int k;
        char x;
        cin >> k >> x;
        sum -= str[k] - 'a' + 1;
        for (int i = 1; i <= str[k] - 'a' + 1; i++) modify(i, 1, 1, k, -1, 1, n);
        for (int i = str[k] - 'a' + 2; i <= 26; i++) modify(i, 1, 1, k, 1, 1, n);
        str[k] = x;
        sum += x - 'a' + 1;
        for (int i = 1; i <= x - 'a' + 1; i++) modify(i, 1, 1, k, 1, 1, n);
        for (int i = x - 'a' + 2; i <= 26; i++) modify(i, 1, 1, k, -1, 1, n);
        query();
    }
    return 0;
}
posted @ 2025-11-15 17:23  tony0530  阅读(0)  评论(0)    收藏  举报