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 }

 

posted @ 2016-11-15 14:23  llysrv  阅读(129)  评论(0编辑  收藏  举报