import sys n = int(sys.stdin.readline()) s = sys.stdin.readline() # 1101、 11011 # 1 (11, 1) (110 10 0) (1101 101 01 1) (11011, 1011, 011, 11, 1) # 1 (1, 1) (2, 2, 1) ( 3, 3, 2, 1) (3, 3, 2, 1, 1) # 1 2 5 9 1101 ans = 1 pre = 1 i = 1 while i < n: if s[i] == s[i - 1]: pre = pre + 1 else: pre = pre + i + 1 ans += pre i += 1 print(ans)
枚举前i个的每次新增的子串观察规律,最终结果接新增的加起来,假设是11011所有结果如下:(1) (11, 1) (110 10 0) (1101 101 01 1) (11011, 1011, 011, 11, 1)
可以看到
- 当新增加与之前不一致时,比如从(11, 1)-》(110, 10, 0), 分数对应(1, 1) ->(2, 2, 1) 需要在之前那层计算上每一个都+ 1, 同时加上新增的长度为1的结果。
- 当新增加的与末尾一样时,(1101 101 01 1) -》(11011, 1011, 011, 11, 1), 分数对应( 3, 3, 2, 1) -》 (3, 3, 2, 1, 1), 可以看到只是多了一个新增的1,其他的与之前计算的那层一样。
所以:使用pre保存上一次计算结果,该次计算结果根据是否与结尾相同,pre分别变为 pre + 1和 pre + (之前长度每个多1) + 1
累加每一次的结果。