思路: 链表模拟。 比如样例 koyomi 对26个字母 都创建一条链表,比如字母’o’ 2->3->-1(前向星逆)
对于每个询问 mi(活力值) ci(字母) 有滑动窗口模拟(队列) 对于链表下一跳,当前活力值够就跳。进队,更新。。不够,就队头往后缩。 恢复活力值,继续判断能否往后跳…….直到链表的尽头。
#include <cstdio>
#include <bitset>
#include <iostream>
#include <set>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <map>
#include <queue>
#include<stdio.h>
#include<string.h>
#include <vector>
using namespace std;
#define INF 0x3f3f3f3f
#define ll long long
const int maxn=1000000;
int n;
char s[3000];
bool cmp(const int &e1,const int &e2){
return e1>e2;
}
int head[3000];
int tot;
void init(){
for(int i=0;i<30;i++)head[i]=-1;
tot=0;
}
struct Edge{
int to,next,w;
}e[maxn];
void addedge(int from,int to,int w){
e[tot].to=to;e[tot].next=head[from];e[tot].w=w;head[from]=tot++;
}
int que[100000];
int main() {
if(fopen("H:\\acm.txt", "r")!=NULL){
freopen("H:\\acm.txt","r",stdin);
}
while(scanf("%d",&n)!=EOF){
int vis[50];memset(vis,0,sizeof(vis));
scanf("%s",s+1);
init();
for(int i=0;i<26;i++){
char x=i+'a';
for(int j=1;j<=n;j++){
int sb=j;
if(s[j]=='a'+i){
int w=1;
while(j+1<=n&&s[j+1]=='a'+i){
w++; j++;
}
addedge(i,sb,w);
}
}
}
for(int i=0;i<26;i++){
int u=head[i]; head[i]=-1;
for(;u!=-1;u=e[u].next){
addedge(i,e[u].to,e[u].w);
}
}
int qn,q;char g[10];
cin>>qn;
for(int ii=1;ii<=qn;ii++){
cin>>q>>g;
int stq=q;
int st=0,ed=0;
int now,res=0;
int u=g[0]-'a';
if(head[u]==-1){
printf("%d\n",min(q,n) );continue;
}
int final_res=0;
int ei=head[u];
res+=e[ei].w;
int k=e[ei].next;
que[ed++]=ei;
final_res=max(final_res,res);
final_res=max(final_res,min(res+q,n));
for( ;k!=-1;k=e[k].next ){
int len=e[k].to-(e[que[ed-1]].to+e[que[ed-1]].w );
if(len<=q){
q-=len;
res+=len+e[k].w;
que[ed++]=k;
final_res=max(final_res,res);
final_res=max(final_res,min(res+q,n));
continue;
}
while(ed-st>=2){
int tlen=e[que[st+1]].to-(e[que[st]].to+e[que[st]].w) ;
q+=tlen;
res-=tlen+e[que[st]].w;
st++;
if(len<=q){
break;
}
}
if(len<=q){
q-=len;
res+=len+e[k].w;
que[ed++]=k;
final_res=max(final_res,res);
final_res=max(final_res,min(res+q,n) );
continue;
}else{
final_res=max(final_res,min(res+q,n) );
res=0;st=0,ed=0;q=stq;
res+=e[k].w;
que[ed++]=k;
final_res=max(final_res,res);
final_res=max(final_res,min(res+q,n) );
}
}
if(q>0){
final_res=max(final_res,min(res+q,n) );
}
printf("%d\n",final_res);
}
}
return 0;
}