CF Round #418( Div.2) An impassioned circulation of affection

来源:互联网 发布:织梦tag标签伪静态 编辑:程序博客网 时间:2024/06/12 22:34

C. An impassioned circulation of affection


time limit per test 2seconds


memory limit per test     256megabytes


Nadeko's birthday is approaching! As she decorated the room forthe party, a long garland of Dianthus-shaped paper pieces was placed on aprominent part of the wall. Brother Koyomi will like it!

Still unsatisfied with the garland, Nadeko decided to polish itagain. The garland has n pieces numbered from 1 to n from left to right, and the i-th piece has a colour si, denoted by a lowercase English letter. Nadeko will repaint at mostm of the pieces to give each of them anarbitrary new colour (still denoted by a lowercase English letter). After thiswork, she finds out all subsegments of the garland containing pieces of onlycolourc — Brother Koyomi's favourite one, and takes the length of thelongest among them to be theKoyomity of the garland.

For instance, let's say the garland is represented by "kooomo", and Brother Koyomi's favouritecolour is "o".Among all subsegments containing pieces of "o" only, "ooo" is the longest, with a length of3.Thus the Koyomity of this garland equals 3.

But problem arises as Nadeko is unsure about Brother Koyomi'sfavourite colour, and has swaying ideas on the amount of work to do. She has q plans on this, each of which can beexpressed as a pair of an integer mi and a lowercase letter ci, meanings of which are explained above. You are to find out themaximum Koyomity achievable after repainting the garland according to each plan.

Input

The first line of input contains a positive integern (1 ≤ n ≤ 1 500) — the length of thegarland.

The second line containsn lowercase English letters s1s2...sn as a string — the initialcolours of paper pieces on the garland.

The third line contains a positive integerq (1 ≤ q ≤ 200 000) — the number ofplans Nadeko has.

The nextq lines describe one plan each: the i-th among them contains an integer mi (1 ≤ mi ≤ n) — the maximum amount of pieces to repaint, followed by aspace, then by a lowercase English letterci — Koyomi's possible favourite colour.

Output

Outputq lines: for each work plan, output one line containing an integer— the largest Koyomity achievable after repainting the garland according to it.

Examples

Input

6
koyomi
3
1 o
4 o
4 m

Output

3
6
5

Input

15
yamatonadeshiko
10
1 a
2 a
3 a
4 a
5 a
1 b
2 b
3 b
4 b
5 b

Output

3
4
5
7
8
1
2
3
4
5

Input

10
aaaaaaaaaa
2
10 b
10 z

Output

10
10

Note

In the first sample, there are three plans:

·  In the first plan, at most1 piece can be repainted. Repainting the"y"piece to become "o" results in "kooomi", whose Koyomity of 3 is the best achievable;

·  In the second plan, at most4 pieces can be repainted, and "oooooo" results in a Koyomity of 6;

·  In the third plan, at most4 pieces can be repainted, and "mmmmmi" and "kmmmmm" both result in a Koyomity of 5.



题意:给出一个只含小写字母的字符串,并给出q个询问,每个询问有一个m值和一个小写字母cc,我们可以把原字符串中任意m个小写字母变成任意的小写字母,问改变后cc在字符串中最长的连续长度为多少。

思路:这道题看了看数据觉得暴力应该不可以,但比赛结束后看了dalao的思路才发现暴力也可以QAQ。我们可以依次遍历字符串,先指定一个起点,然后把终点一点点往后移,遇到不是我们要的字符就把它变成我们要的,当可以改变的次数用光后结束,更新最大值并将起点往后移,以此类推。


1107ms

#include <cstdio>#include <cstring>#include <vector>#include <algorithm>using namespace std;#define mst(a,b) memset((a),(b),sizeof(a))#define f(i,a,b) for(int i=(a);i<(b);++i)#define rush() int T;scanf("%d",&T);while(T--)#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1typedef long long ll;const int maxn= 1505;const ll mod = 1e9+7;const int INF = 0x3f3f3f3f;const double eps = 1e-6;int n,q;char str[maxn];int num[30][maxn];int s[maxn];void Get_Count()      //预处理出num数组{                     //num[i][j]的含义为在原字符串前n个字符中不是字母(i+'a')的个数    mst(num,0);    for(int i=1; i<=n; i++)    {        s[i]=str[i]-'a';        for(int j=0; j<26; j++)        {            num[j][i]=num[j][i-1];            if(s[i]!=j)                num[j][i]++;        }    }}int main(){    char c[5];    int k;    while(~scanf("%d",&n))    {        scanf("%s",str+1);        Get_Count();        scanf("%d",&q);        for(int i=0;i<q;i++)        {            scanf("%d%s",&k,c);            int id=c[0]-'a';            /*if(num[id][n]==n)   //想优化的,但貌似跑的时间更长了。。。            {                printf("%d\n",k);                continue;            }*/            int *tmp=num[id];            int end=1;            int ans=0;            for(int i=1;i<=n;i++)            {                while(end+1<=n&&tmp[end+1]-tmp[i-1]<=k)                    end++;                int len=end-i+1;                ans=max(ans,len);            }            printf("%d\n",ans);        }    }    return 0;}

上面这种方法是在线查询,时间复杂度z最坏约为O(n*n*q),注意到26种字母,改变次数最多为1500,1500*26=39000<200000,故我们可以采用离线预处理的方法,预处理出每个字母改变任意次数得到的值,时间复杂度就降到了min(n*n*26,q)。


296ms

#include <cstdio>#include <cstring>#include <vector>#include <algorithm>using namespace std;#define mst(a,b) memset((a),(b),sizeof(a))#define f(i,a,b) for(int i=(a);i<(b);++i)#define rush() int T;scanf("%d",&T);while(T--)#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1typedef long long ll;const int maxn= 1505;const ll mod = 1e9+7;const int INF = 0x3f3f3f3f;const double eps = 1e-6;int n,q;char str[maxn];int num[30][maxn];int s[maxn];int ans[30][maxn];void Get_Count()      //预处理出num数组{    //num[i][j]的含义为在原字符串前n个字符中不是字母(i+'a')的个数    mst(num,0);    for(int i=1; i<=n; i++)    {        s[i]=str[i]-'a';        for(int j=0; j<26; j++)        {            num[j][i]=num[j][i-1];            if(s[i]!=j)                num[j][i]++;        }    }}void solve(){    mst(ans,0);    for(int i=0; i<26; i++)        for(int k=1; k<=n; k++)        {            int *tmp=num[i];            int end=1;            int tot=0;            for(int j=1; j<=n; j++)            {                while(end+1<=n&&tmp[end+1]-tmp[j-1]<=k)                    end++;                int len=end-j+1;                tot=max(tot,len);            }            ans[i][k]=tot;        }}int main(){    char c[5];    int k;    while(~scanf("%d",&n))    {        scanf("%s",str+1);        Get_Count();        solve();        scanf("%d",&q);        for(int i=0; i<q; i++)        {            scanf("%d%s",&k,c);            int id=c[0]-'a';            printf("%d\n",ans[id][k]);        }    }    return 0;}


阅读全文
0 0