题意:给出26个字母每个字母的价值,问字符串中有多少个满足以下条件的子串:
1.子串的第一个和最后一个相同
2.子串除了头和尾的其他字符的价值加起来和尾0
这题普通方法应该是O(n^2),但是在1e5的条件下肯定会超时,所以学习了大力学长奥义的O(n)方法。具体方法也说不清楚,看代码吧,很短,也容易看懂。只能说,相当奥义的方法。。
代码如下:
1 #include <stdio.h> 2 #include <algorithm> 3 #include <string.h> 4 #include <map> 5 using namespace std; 6 typedef long long ll; 7 8 char s[100000+5]; 9 ll val[100000+5]; 10 map<ll,int> M[26]; 11 12 int main() 13 { 14 for(int i=0;i<26;i++) scanf("%I64d",val+i); 15 scanf("%s",s+1); 16 int len = strlen(s+1); 17 18 ll pre = 0,ans = 0; 19 for(int i=1;i<=len;i++) 20 { 21 int m = s[i] - 'a'; 22 ans += M[m][pre]; 23 pre += val[m]; 24 M[m][pre] ++; 25 } 26 printf("%I64d ",ans); 27 }