cf--contest1311--C. Perform the Combo+推理(前缀和)

传送门

http://codeforces.com/contest/1311/problem/C

题意

有一个字符串按键,你只能从第一个字符按到最后才能完成,现在有m次操作,每次操作使得x位置损坏,损坏键第二次就好了,每次损坏后都要从头开始按,问进行m次操作后,每个按键按了几次。

思路

这个题是卡时间的题,暴力肯定是要出问题的,因为n²(n<2e5)将会tle;
所以,需要优化算法。可以把每次按键的位置存起来,然后第一个字母肯定是被按了m次,下一个损坏按键的位置就是m-当前位置的次数。依次往后推即可。

AC代码
#include<cstdio>
#include<cstring>
using namespace std;
const int MAXN=2e5+5;
char str[MAXN];
int ans[26],arr[MAXN];//ans数组存放每个字母键的次数,arr数组存放损坏位置数
int main()
{
	int t;
	scanf("%d",&t);
	while(t--)
	{
		memset(ans,0,sizeof(ans));
		memset(arr,0,sizeof(arr));
		int n,m;
		scanf("%d%d",&n,&m);
		getchar();
		for(int i=1;i<=n;i++)	scanf("%c",&str[i]);
		getchar();
		for(int i=1;i<=n;i++)	ans[str[i]-'a']++;
		for(int i=1;i<=m;i++)
		{
			int x;
			scanf("%d",&x);
			arr[x]++;
		}
		int mx=m;
		for(int i=1;i<=n;i++)
		{
			ans[str[i]-'a']+=m;//第i个键按了多少次 
			m-=arr[i];//第一个键按m次,依次递减 
		}
		printf("%d",ans[0]);
		for(int i=1;i<26;i++)
			printf(" %d",ans[i]);
		puts("");
	}
	return 0;
}
发布了39 篇原创文章 · 获赞 1 · 访问量 561

猜你喜欢

转载自blog.csdn.net/qq_45249273/article/details/104505275