P6416 题解
凌驾于算法之上的思路:
对于第 x 行,在它之前的第
细节:
直接求
那么我们就可以刷暴力了。但是很明显,会超时。令
PS :这题卡空间,所以需要分成一个一个字母处理。
#include<bits/stdc++.h>
using namespace std;
const int maxn=1000005;
long long n,m,Ans[50005];
int q,Q,sum[maxn];
char a[maxn];
struct yxy{
int id;long long x;char C;
bool operator<(const yxy b)const{return C<b.C;}
}t[50005];
long long read(){
long long ret=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-f;ch=getchar();}
while(isdigit(ch))ret=ret*10+ch-'0',ch=getchar();
return ret*f;
}
void calc(int k){
char ch=t[k].C;
long long L,R,S;
if(t[k].x&1)L=(long long)((t[k].x%m))*((t[k].x-1)/2%m);
else L=(long long)((t[k].x/2%m))*((t[k].x-1)%m);
L++;
L%=m;if(L==0)L=m;
if(L+t[k].x-1<=m){
Ans[t[k].id]=sum[L+t[k].x-1]-sum[L-1];
// if(L+t[k].x-1>m)Ans[t[k].id]+=sum[t[k].x-m+L-1];
}//t[k].x -(m-L+1)==t[k].x-m+L-1
else {
Ans[t[k].id]=sum[m]-sum[L-1];
t[k].x-=(m-L+1);L=1;
long long size=t[k].x/m;
Ans[t[k].id]+=(long long)size*sum[m];
R=t[k].x%m;
if(R!=0)Ans[t[k].id]+=sum[R];
}
}
int main(){
n=read();
scanf("%s",a+1); m=strlen(a+1);
// for(int i=1;i<=m;i++){
// for(int j=0;j<26;j++)sum[i][j]=sum[i-1][j];
// sum[i][a[i]-'A']++;
// }
q=read();
while(q--){
long long x=read();
char C=getchar();
while(C<'A'||C>'Z')C=getchar();
t[++Q]=(yxy){Q,x,C};
}
sort(t+1,t+1+Q);
for(int i=1;i<=Q;){
int j=i;
for(int K=1;K<=m;K++)sum[K]=sum[K-1]+(a[K]==t[i].C);
while(t[i].C==t[j].C)calc(j),j++;
i=j;
}
for(int i=1;i<=Q;i++)printf("%lld\n",Ans[i]);
return 0;
}