CF1311C. Perform the Combo題解

description:

  • 給定一個長度爲 nn 小寫字母字符串 ss。(這裏默認下標從 11 開始)
  • 給定一個長度爲 mm 的數列 pip_i
  • 對於每一個 pip_i,表示你要統計 s1spis_1\sim s_{p_i}所對應的字母各一次。
  • 最終,你還要統計整個字符串的字母各一次。
  • 你需要求出 2626 個小寫字母中每個字母被統計過的次數。
  • 多組數據,數據組數不超過 10410^42n2×1052\le n\le 2\times 10^51m2×1051\le m\le 2\times 10^5
  • translate by @ShineEternal

solution:

數據範圍比較大,我們沒法一一枚舉,於是可以使用前綴和。

用前綴和將每一個位置的各個字母的出現次數進行提前統計,遇到 pip_i 的時候 O(1)O(1) 查詢就行了。

code:

#include<cstdio>
#include<algorithm>
using namespace std;
int p[200005];
char s[200005];
int mp[200005][30];
int Mp[30];
int main()
{
	int T;
	scanf("%d",&T);
	while(T--)
	{
		for(int i=1;i<=30;i++)Mp[i]=0;
		int n,m;
		scanf("%d%d",&n,&m);
		scanf("%s",s);
		//printf("%s\n",s);
		for(int i=1;i<=m;i++)
		{
			scanf("%d",&p[i]);
		}
		p[m+1]=n;
		m++;
		for(int i=1;i<=26;i++)mp[0][i]=0;
		mp[0][s[0]-'a'+1]++;
		for(int i=1;i<n;i++)
		{
			for(int j=1;j<=26;j++)mp[i][j]=mp[i-1][j];
			mp[i][s[i]-'a'+1]++;
		}
		for(int i=1;i<=m;i++)
		{
			for(int j=1;j<=26;j++)
			{
				Mp[j]+=mp[p[i]-1][j];
			}
		}
		for(int i=1;i<=26;i++)
		{
			printf("%d ",Mp[i]);
		}
		printf("\n");
	}
	return 0;
} 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章