题目链接: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; }