Codeforces 519D A and B and Interesting Substrings(二维map+前缀和)

题目链接:http://codeforces.com/problemset/problem/519/D

题目大意:
给你一串字符串s仅由小写字母组成,并且对于'a'~'z'都给了一个值。求子串t满足t的开头和结尾字符相同,且中间的字符的值相加为0,
求子串t的数目。
解题思路:
设置map<LL,int>mp[26]这样的二维map,记录对应以每个字母结尾的前缀和的值的出现次数。
然后计算前缀和sum,每次计算sum+val[s[i]]前,先计算ans,因为sum[i-1]-sum[x]==0才能说明sum(i-1~x+1)这一段为0 。

代码

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<algorithm>
 4 #include<vector>
 5 #include<string>
 6 #include<string.h>
 7 #include<cctype>
 8 #include<math.h>
 9 #include<stdlib.h>
10 #include<stack>
11 #include<queue>
12 #include<set>
13 #include<map>
14 #define lc(a) (a<<1)
15 #define rc(a) (a<<1|1)
16 #define MID(a,b) ((a+b)>>1)
17 #define fin(name)  freopen(name,"r",stdin)
18 #define fout(name) freopen(name,"w",stdout)
19 #define clr(arr,val) memset(arr,val,sizeof(arr))
20 #define _for(i,start,end) for(int i=start;i<=end;i++)  
21 #define FAST_IO ios::sync_with_stdio(false);cin.tie(0);
22 using namespace std;
23 typedef long long LL;
24 const int N=1e5+5;
25 const LL INF64=1e18;
26 const int INF=0x3f3f3f3f;
27 const double eps=1e-10;
28 
29 int val[30];
30 map<LL,int>mp[30];
31 
32 int main(){
33     for(int i=0;i<26;i++){
34         cin>>val[i];
35     }
36     string str;
37     cin>>str;
38     LL sum=0,ans=0;
39     for(int i=0;i<str.length();i++){
40         int ch=str[i]-'a';
41         //注意先计算ans, 再sum+=val[ch]
42         //因为sum[i-1]-sum[x]==0才能说明sum(i-1~x+1)这一段为0 
43         ans+=mp[ch][sum];
44         sum+=val[ch];
45         mp[ch][sum]++;
46     }
47     cout<<ans<<endl;
48     return 0;
49 }

 

posted @ 2018-11-01 20:35  Yeader  阅读(331)  评论(0编辑  收藏  举报