传送门
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;
}