Nadeko’s birthday is approaching! As she decorated the room for the party, a long garland of Dianthus-shaped paper pieces was placed on a prominent part of the wall. Brother Koyomi will like it!
Still unsatisfied with the garland, Nadeko decided to polish it again. The garland has n pieces numbered from 1 to n from left to right, and the i-th piece has a colour s i s_i si, denoted by a lowercase English letter. Nadeko will repaint at most m of the pieces to give each of them an arbitrary new colour (still denoted by a lowercase English letter). After this work, she finds out all subsegments of the garland containing pieces of only colour c — Brother Koyomi’s favourite one, and takes the length of the longest among them to be the Koyomity of the garland.
For instance, let’s say the garland is represented by “kooomo”, and Brother Koyomi’s favourite colour is “o”. Among all subsegments containing pieces of “o” only, “ooo” is the longest, with a length of 3. Thus the Koyomity of this garland equals 3.
But problem arises as Nadeko is unsure about Brother Koyomi’s favourite colour, and has swaying ideas on the amount of work to do. She has q plans on this, each of which can be expressed as a pair of an integer $m_i a n d a l o w e r c a s e l e t t e r ∗ and a lowercase letter * andalowercaseletter∗c_i$*, meanings of which are explained above. You are to find out the maximum Koyomity achievable after repainting the garland according to each plan.
The first line of input contains a positive integer n (1 ≤ n ≤ 1 500) — the length of the garland.
The second line contains n lowercase English letters s1s2… s n s_n sn as a string — the initial colours of paper pieces on the garland.
The third line contains a positive integer q (1 ≤ q ≤ 200 000) — the number of plans Nadeko has.
The next q lines describe one plan each: the i-th among them contains an integer m i m_i mi (1 ≤ m i m_i mi ≤ n) — the maximum amount of pieces to repaint, followed by a space, then by a lowercase English letter c i c_i ci — Koyomi’s possible favourite colour.
Output q lines: for each work plan, output one line containing an integer — the largest Koyomity achievable after repainting the garland according to it.
Input
6koyomi31 o4 o4 m
Output
365
Input
15yamatonadeshiko101 a2 a3 a4 a5 a1 b2 b3 b4 b5 b
Output
3457812345
Input
10aaaaaaaaaa210 b10 z
Output
1010
In the first sample, there are three plans:
这道题的核心思想是通过预处理来减少查询时的计算量,从而提高效率。我们可以通过枚举所有可能的区间(O(n^2)
)以及所有可能的目标颜色(26个字母),计算每个区间内需要多少修改才能将所有字符变为目标颜色,并将这些结果保存下来。这样在查询时,时间复杂度就降到了常数级别。
查询次数与预处理的关系:
n
,最大可能的答案数量是 1500 * 26 = 39000
,远小于 q = 200000
,所以这意味着我们需要进行有效的预处理,避免在每个查询时进行复杂的计算。预处理思路:
c
(26个字母),我们需要计算所有子区间 [i, j]
需要多少修改才能使得该区间内的所有字符都变成颜色 c
。优化:
O(1)
时间内计算任意区间内某个字符的出现次数。这样我们就能在 O(n^2)
的时间复杂度内处理所有区间,之后再通过枚举颜色来进一步降低复杂度。O(n^2 * 26)
,这对于 n ≤ 1500
是可以接受的。最终的查询处理:
n
(即最大连续长度是整个字符串)。#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define endl '\n'
#define int long long
#define Max(a, b) (((a) > (b)) ? (a) : (b))
#define Min(a, b) (((a) < (b)) ? (a) : (b))
#define BoBoowen ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
using namespace std;
const int inf = 1e9 + 7;
const int N = 1500 + 10;
int n;
string s;
int q;
int qz[30][N];
int dp[30][N];
map<char, int> mp;
int ask(int can, char c)
{
int x = c - 'a';
for (int i = 1; i <= n; ++i)
{
for (int j = 1; j <= n; ++j)
{
if (i > j)
{
continue;
}
dp[x][j - i + 1 - (qz[x][j] - qz[x][i - 1])] = max((dp[x][j - i + 1 - (qz[x][j] - qz[x][i - 1])]), (j - i + 1));
}
}
for (int i = 1; i <= n; ++i)
{
dp[x][i] = max(dp[x][i], dp[x][i - 1] + 1);
}
mp[c] = 1;
return min(dp[x][can], n);
}
void solved()
{
cin >> n >> s >> q;
s = ' ' + s;
for (int i = 0; i < 26; ++i)
{
for (int j = 1; j <= n; ++j)
{
if (s[j] - 'a' != i)
{
qz[i][j] = qz[i][j - 1];
}
else
{
qz[i][j] = qz[i][j - 1] + 1;
}
}
}
while (q--)
{
int can;
char c;
cin >> can >> c;
if (mp[c] == 0)
{
cout << ask(can, c) << endl;
}
else
{
cout << min(dp[c - 'a'][can], n) << endl;
}
}
}
signed main()
{
BoBoowen;
int T = 1;
// cin >> T;
while (T--)
{
solved();
}
}
qz
数组的计算:
qz[c][i]
表示从第1个字符到第i个字符中,目标颜色字符的个数。qz[c][i]
表示在字符串 s
中,前 i
个字符中有多少个目标颜色 c
。precompute
函数:
[i, j]
,然后使用前缀和来计算区间内需要修改的字符数量。c
,我们计算当前区间需要修改的字符数量,并更新 ans[i][j]
,即使区间 [i, j]
修改成目标颜色需要的最小修改次数。查询处理:
预处理阶段:
c
(共26个),我们计算前缀和的时间复杂度是 O(n)
.[i, j]
,每次计算一个区间所需要的修改次数,时间复杂度是 O(n^2)
.O(n^2 * 26)
,即 O(n^2)
。查询阶段:
O(1)
,因为查询操作仅仅是通过已预处理的结果来得到答案。通过前缀和的优化,我们将原本的暴力枚举区间的时间复杂度降低到了 O(n^2 * 26)
,这是可以接受的,因此这个方法能够有效地处理大规模的输入数据,满足题目的时间要求。