传送门:http://codeforces.com/contest/519/problem/D
题意:给出一个字符串,给出每个字母的权值,求字符串的子串中首尾相等,除去首尾字母的权值和为0的数量。
思路:
从前到后扫描字符串,计算前缀和,每次将前缀和Hash,然后每次查询与当前位字母相同的前缀和 前缀的数量,间接地计算出字符串的数量。
代码:
#include <bits/stdc++.h>
using namespace std;
#define ll __int64
const int N=1e5+10;
typedef std::map<ll, ll> mp;
mp dp[27];
int a[27];
char s[N];
int main(){
for(int i=0; i<26; i++)scanf("%d", &a[i]);
scanf("%s", s);
int n=strlen(s);
ll ans=0, sum=0;
for(int i=0; i<n; i++){
int now=s[i]-'a';
ans+=dp[now][sum];
sum+=a[now];
dp[now][sum]++;
}
printf("%lld\n", ans);
return 0;
}