题目地址:http://codeforces.com/contest/519/problem/D
26个字母分别给出喜爱程度,用正负整数表示。然后给出一个只包含英文字母的字符串S,如果T为S子串,T第一个字符与最后一个字符相同,且除第一个和最后一个字符外,字符喜爱程度和为0,则为符合要求的子串。求共有多少符合要求的子串。
这里如果维护前缀和sum[i],S[i]=S[k](k>i),那么中间字符喜爱程度和为0就转换为sum[i]=sum[k]-val[k]。那开个map<LL,int>m[26]就可以了。
1 #include<cstdio> 2 #include<iostream> 3 #include<string.h> 4 #include<algorithm> 5 #include<math.h> 6 #include<stdbool.h> 7 #include<map> 8 #include<stack> 9 using namespace std; 10 #define clr(x,y) memset(x,y,sizeof(x)) 11 #define sqr(x) ((x)*(x)) 12 #define rep(i,a,b) for(int i=(a);i<=(b);i++) 13 #define LL long long 14 #define INF 0x3f3f3f3f 15 #define A first 16 #define B second 17 18 int main() 19 { 20 int val[30]; 21 char a[100005]; 22 LL rez=0,sum=0; 23 24 map<LL,int> m[30]; 25 for(int i=0;i<26;i++) { 26 scanf("%d",&val[i]); 27 } 28 getchar(); 29 gets(a); 30 31 int len=strlen(a); 32 for(int i=0;i<len;i++) { 33 a[i]-='a'; 34 sum+=val[a[i]]; 35 rez+=m[a[i]][sum-val[a[i]]]; 36 m[a[i]][sum]++; 37 } 38 39 cout<<rez<<endl; 40 41 }