题意:
对于26个字母 每个字母分别有一个权值 给出一个字符串,找出有多少个满足条件的子串, 条件:1、第一个字母和最后一个相同,2、除了第一个和最后一个字母外,其他的权和为0 思路: 预处理出sum[i]:s[0~i]的和 开26个map<LL, LL>numV 分别表示 每个字母前缀和 的个数 例如处理到第i个元素,且numV[s[i]-'a'][sum[i]-v[s[i] - 'a']] (值为2) 表示在处理到的元素之前 以s[i]结尾的前缀和为sum[i]-v[s[i]-'a']的个数有2个 所以答案就要加2(因为前面已经组成过这个值,又出现的原因就是他的值变为了0)
1 const int maxv = 30; 2 int v[maxv]; 3 mapnumV[maxv]; 4 5 const int maxn = 100000 + 10; 6 char s[maxn]; 7 LL sum[maxn]; 8 void init() 9 {10 for (int i = 0; i < 26; i++)11 {12 scanf("%d", v + i);13 }14 scanf(" ");15 gets(s);16 }17 18 void solve()19 {20 int len = strlen(s);21 sum[0] = v[s[0]-'a'];22 for (int i = 1; i < len; i++)23 {24 sum[i] = sum[i-1] + v[s[i]-'a'];25 }26 27 LL ans = 0;28 for (int i = 0; i < len; i++)29 {30 ans += numV[s[i]-'a'][sum[i] - v[s[i] - 'a']];31 numV[s[i]-'a'][sum[i]]++;32 }33 printf("%lld\n", ans);34 }35 36 int main()37 {38 init();39 solve();40 return 0;41 }