CodeForces 519D A and B and Interesting Substrings ——(奥义字符串)

O(n)解法求特定子串数量
本文介绍了一种高效算法,用于解决特定条件下的子串计数问题。该算法可在O(n)时间内找出所有满足首尾字符相同且中间字符价值总和为0的子串数量。

  题意:给出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\n",ans);
27 }

 

转载于:https://www.cnblogs.com/zzyDS/p/5650397.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值