1. 程式人生 > >Codeforces 519D A and B and Interesting Substrings(二維map+前綴和)

Codeforces 519D A and B and Interesting Substrings(二維map+前綴和)

substring open 一段 ast n) 題目 rest ons 記錄

題目鏈接: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 }

Codeforces 519D A and B and Interesting Substrings(二維map+前綴和)