Codeforces Round #294 (Div. 2) D. A and B and Interesting Substrings
题意:
对于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 map<LL, LL> numV[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 }