题目链接:
题目大意:
给出一个字符串,给出每个字母的权值,求字符串的子串中首尾相等,除去首尾字母的权值和为0的数量。
题目分析:
从前到后扫描字符串,计算前缀和,每次将前缀和Hash,然后每次查询与当前位字母相同的前缀和与当前前缀和相等的前缀的数量,间接地计算出字符串的数量。
AC代码:
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <map>
#define M 27
#define N 100007
using namespace std;
typedef long long LL;
typedef map<LL,LL> Dic;
Dic dic[M];
int a[M];
char s[N];
int main ( )
{
for ( int i = 0 ; i < 26 ; i++ )
{
dic[i].clear();
scanf ( "%d" , &a[i] );
}
scanf ("%s" , s );
int n = strlen ( s );
LL sum = 0;
LL ans = 0;
for ( int i = 0; i < n ; i++ )
{
int x = s[i]-'a';
LL y = dic[x][sum];
sum += a[x];
ans += y;
dic[x][sum]++;
}
printf ( "%I64d\n" , ans );
}