codeforces 814 C. An impassioned circulation of affection(二分+思维)

题目链接:http://codeforces.com/contest/814/problem/C

题意:给出一串字符串然后q个询问,问替换掉将m个字符替换为字符c,能得到的最长的连续的字符c是多长

题解:预处理dp[i][j]表示第i种字幕添加j个最长的连续为多长。然后与处理一下sum[j]表示前j个里有几个不是第i种字母的。

然后for一遍二分一下。更新dp。

#include <iostream>
#include <cstring>
#include <vector>
#include <cstdio>
using namespace std;
char s[2000];
int dp[27][2000] , sum[2000];
int binsearch(int l , int r , int num , int pos) {
    int mid = (l + r) >> 1;
    while(l <= r) {
        mid = (l + r) >> 1;
        if(sum[mid] - sum[pos] <= num) l = mid + 1;
        else r = mid - 1;
    }
    return r;
}
int main() {
    int n;
    scanf("%d" , &n);
    scanf("%s" , (s + 1));
    memset(dp , 0 , sizeof(dp));
    for(int i = 0 ; i < 26 ; i++) {
        int id = -1;
        memset(sum , 0 , sizeof(sum));
        for(int j = 1 ; j <= n ; j++) {
            if(s[j] - 'a' == i) {
                id = i;
                break;
            }
        }
        if(id == -1) {
            for(int j = 1 ; j <= n ; j++) dp[i][j] = j;
        }
        else {
            for(int j = 1 ; j <= n ; j++) {
                sum[j] += sum[j - 1];
                if(s[j] - 'a' != id) {
                    sum[j]++;
                }
            }
            for(int l = 1 ; l <= n ; l++) {
                for(int j = 1 ; j <= n ; j++) {
                    int pos = binsearch(j , n , l , j - 1);
                    //if(i == 14) cout << pos << endl;
                    dp[i][l] = max(dp[i][l] , pos - j + 1);
                }
            }
        }
    }
    int q;
    scanf("%d" , &q);
    while(q--) {
        int m;
        char c[10];
        scanf("%d%s" , &m , c);
        int id = c[0] - 'a';
        printf("%d
" , dp[id][m]);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/TnT2333333/p/6959550.html