CF1311C Perform the Combo 题解

题目

链接

https://www.luogu.com.cn/problem/CF1311C

字面描述

题面翻译

一台机器准备要打印一篇文章,有 m m m 个打印操作

给出操作序列 p 1 , p 2 , … , p m p_1,p_2, \dots ,p_m p1,p2,,pm 和 长度为 n n n 的字符串 s s s
对于每个 ( 1 ≤ i ≤ m ) (1 \le i \le m) (1im) p i p_i pi 表示该机器将位置 1 ∼ p i 1\sim p_i 1pi 上的所有字母打印了出来
最后,在所有操作做完后,该机器又将整个字符串 s s s 打印了出来

请求出字母表中每个字母在文章中出现了多少次

输入格式

第一行一个整数 T T T,表示数据的组数
对于每组数据:
第一行两个整数 n , m n,m n,m,分别表示字符串长度和操作数
第二行一个长度为 n n n 的,由小写字母构成的字符串 s s s
第三行 m m m 个整数,表示操作序列 p p p

输出格式

T T T 行,每行 26 26 26 个整数,分别表示每个字母出现的次数
每行第一个数表示 a \texttt{a} a 出现的次数,第二个数表示 b \texttt{b} b 出现的次数,以此类推

说明与提示

1 ≤ T ≤ 1 0 4 1\le T \le 10^4 1T104
2 ≤ n ≤ 2 ⋅ 1 0 5 2 \le n \le 2 \cdot 10^5 2n2105
1 ≤ m ≤ 2 ⋅ 1 0 5 1 \le m \le 2 \cdot 10^5 1m2105
∑ n , ∑ m ≤ 2 ⋅ 1 0 5 \sum n,\sum m \le 2 \cdot 10^5 n,m2105
1 ≤ p i < n 1 \le p_i <n 1pi<n

感谢 @_Wolverine 提供的翻译

题目描述

You want to perform the combo on your opponent in one popular fighting game. The combo is the string $ s $ consisting of $ n $ lowercase Latin letters. To perform the combo, you have to press all buttons in the order they appear in $ s $ . I.e. if $ s= $ “abca” then you have to press ‘a’, then ‘b’, ‘c’ and ‘a’ again.

You know that you will spend $ m $ wrong tries to perform the combo and during the $ i $ -th try you will make a mistake right after $ p_i $ -th button ( $ 1 \le p_i < n $ ) (i.e. you will press first $ p_i $ buttons right and start performing the combo from the beginning). It is guaranteed that during the $ m+1 $ -th try you press all buttons right and finally perform the combo.

I.e. if $ s= $ “abca”, $ m=2 $ and $ 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 $ t $ independent test cases.

输入格式

The first line of the input contains one integer $ t $ ( $ 1 \le t \le 10^4 $ ) — the number of test cases.

Then $ t $ test cases follow.

The first line of each test case contains two integers $ n $ and $ m $ ( $ 2 \le n \le 2 \cdot 10^5 $ , $ 1 \le m \le 2 \cdot 10^5 $ ) — the length of $ s $ and the number of tries correspondingly.

The second line of each test case contains the string $ s $ consisting of $ n $ lowercase Latin letters.

The third line of each test case contains $ m $ integers $ p_1, p_2, \dots, p_m $ ( $ 1 \le p_i < n $ ) — the number of characters pressed right during the $ i $ -th try.

It is guaranteed that the sum of $ n $ and the sum of $ m $ both does not exceed $ 2 \cdot 10^5 $ ( $ \sum n \le 2 \cdot 10^5 $ , $ \sum m \le 2 \cdot 10^5 $ ).

It is guaranteed that the answer for each letter does not exceed $ 2 \cdot 10^9 $ .

输出格式

For each test case, print the answer — $ 26 $ integers: the number of times you press the button ‘a’, the number of times you press the button ‘b’, $ \dots $ , the number of times you press the button ‘z’.

样例 #1

样例输入 #1
3
4 2
abca
1 3
10 5
codeforces
2 8 3 2 9
26 10
qwertyuioplkjhgfdsazxcvbnm
20 10 1 2 3 5 10 5 9 4
样例输出 #1
4 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 9 4 5 3 0 0 0 0 0 0 0 0 9 0 0 3 1 0 0 0 0 0 0 0 
2 1 1 2 9 2 2 2 5 2 2 2 1 1 5 4 11 8 2 7 5 1 10 1 5 2

提示

The first test case is described in the problem statement. Wrong tries are “a”, “abc” and the final try is “abca”. The number of times you press ‘a’ is $ 4 $ , ‘b’ is $ 2 $ and ‘c’ is $ 2 $ .

In the second test case, there are five wrong tries: “co”, “codeforc”, “cod”, “co”, “codeforce” and the final try is “codeforces”. The number of times you press ‘c’ is $ 9 $ , ‘d’ is $ 4 $ , ‘e’ is $ 5 $ , ‘f’ is $ 3 $ , ‘o’ is $ 9 $ , ‘r’ is $ 3 $ and ‘s’ is 1 1 1

思路

熟悉的数据范围,熟悉的题目描述,一眼就可以断定是前缀和问题,只不过要记录26个小写字母在原字符串中出现次数,最后询问求和输出

代码实现

#include<bits/stdc++.h>
using namespace std;

const int maxn=2e5+10;
int t,n,m;
char a[maxn];
int x[maxn],ans[40];
int f[maxn][40];
int main(){
	scanf("%d",&t);
	while(t--){
		scanf("%d%d",&n,&m);
		memset(ans,0,sizeof(ans));
		for(int i=1;i<=n;i++){
			scanf(" %c",&a[i]);
			x[i]=a[i]-'a'+1;
		}
		for(int i=1;i<=n;i++){
			for(int j=1;j<=26;j++)f[i][j]=f[i-1][j];
			f[i][x[i]]++;
		}
		while(m--){
			int p;
			scanf("%d",&p);
			for(int i=1;i<=26;i++)ans[i]+=f[p][i];
		}
		for(int i=1;i<=26;i++)printf("%d ",ans[i]+f[n][i]);
		printf("\n");
	}
	
	return 0;
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

materialistOier

我只是一名ssfoier

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值