题目来源:Problem - 1311C - Codeforces
原题:
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output
You want to perform the combo on your opponent in one popular fighting game. The combo is the string ss consisting of nn lowercase Latin letters. To perform the combo, you have to press all buttons in the order they appear in ss. I.e. if s=s="abca" then you have to press 'a', then 'b', 'c' and 'a' again.
You know that you will spend mm wrong tries to perform the combo and during the ii-th try you will make a mistake right after pipi-th button (1≤pi<n1≤pi<n) (i.e. you will press first pipi buttons right and start performing the combo from the beginning). It is guaranteed that during the m+1m+1-th try you press all buttons right and finally perform the combo.
I.e. if s=s="abca", m=2m=2 and p=[1,3]p=[1,3] then the sequence of pressed buttons will be 'a' (here you're making a mistake and start performing the combo from the beginning), 'a', 'b', 'c', (here you're making a mistake and start performing the combo from the beginning), 'a' (note that at this point you will not perform the combo because of the mistake), 'b', 'c', 'a'.
Your task is to calculate for each button (letter) the number of times you'll press it.
You have to answer tt independent test cases.
Input
The first line of the input contains one integer tt (1≤t≤1041≤t≤104) — the number of test cases.
Then tt test cases follow.
The first line of each test case contains two integers nn and mm (2≤n≤2⋅1052≤n≤2⋅105, 1≤m≤2⋅1051≤m≤2⋅105) — the length of ss and the number of tries correspondingly.
The second line of each test case contains the string ss consisting of nn lowercase Latin letters.
The third line of each test case contains mm integers p1,p2,…,pmp1,p2,…,pm (1≤pi<n1≤pi<n) — the number of characters pressed right during the ii-th try.
It is guaranteed that the sum of nn and the sum of mm both does not exceed 2⋅1052⋅105 (∑n≤2⋅105∑n≤2⋅105, ∑m≤2⋅105∑m≤2⋅105).
It is guaranteed that the answer for each letter does not exceed 2⋅1092⋅109.
Output
For each test case, print the answer — 2626 integers: the number of times you press the button 'a', the number of times you press the button 'b', ……, the number of times you press the button 'z'.
题意:给一个由小写字母字符串,和m次失误,按照字符串的顺序按下字母键,失误了就重来,数组记录了在一次输入过程中必定会失误,然后重来,问完整打完一整条字符串,每个按键被摁的次数。
题解思路:可以用一个二维数组记录在输入到第i个字母为止每个键被摁的次数,在到达失误点时,每个字母被摁的次数就可以直接加二维数组中存的相应的值。
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <math.h>
#include<cstring>
#include<queue>
#include<map>
#include<cstdlib>
#include<cstdio>
#include<string>
using namespace std;
int ans[30];//记录26个字母被摁的次数
char s[200030];//保存字符串
int dp[200030][30];//记录在按键过程中相应的每个点被摁的次数
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);//关闭同步流
int t;
cin>>t;
while(t--)//t组数据
{
int n,m;
cin>>n>>m;
for(int i=0;i<=n;++i)//初始化
{
for(int j=0;j<26;j++)
dp[i][j]=0;
}
for(int i=0;i<26;++i)//初始化
ans[i]=0;
scanf("%s",s+1);
for(int i=1;i<=n;i++)
{
dp[i][s[i]-'a']++;//在摁了第i个键后,该字母被摁的次数加1
for(int j=0;j<26;j++)//实际上除了此次被摁的字母比上一步多了一,其余字母都继承上一步
dp[i][j]+=dp[i-1][j];
}
for(int k=0;k<m;++k)//m次失误
{
int x;
cin>>x;
for(int i=0;i<26;i++)//对于此次失误,每个字母加上被摁的次数
ans[i]+=dp[x][i];
}
for(int i=0;i<26;i++)//最终会成功输入一遍,这个也要算进去
ans[i]+=dp[n][i];
for(int i=0;i<26;i++)
if(i!=25)
cout<<ans[i]<<' ';
else
cout<<ans[i];
cout<<'\n';
}
return 0;
}