Count Good Substrings

Count Good Substrings

Time Limit: 2000ms
Memory Limit: 262144KB
This problem will be judged on CodeForces. Original ID: 451D
64-bit integer IO format: %I64d      Java class name: (Any)
 
 
We call a string good, if after merging all the consecutive equal characters, the resulting string is palindrome. For example, "aabba" is good, because after the merging step it will become "aba".

Given a string, you have to find two values:

  1. the number of good substrings of even length;
  2. the number of good substrings of odd length.

Input

The first line of the input contains a single string of length n (1 ≤ n ≤ 105). Each character of the string will be either 'a' or 'b'.

 

Output

Print two space-separated integers: the number of good substrings of even length and the number of good substrings of odd length.

 

Sample Input

Input
bb
Output
1 2
Input
baab
Output
2 4
Input
babb
Output
2 5
Input
babaa
Output
2 7

Hint

In example 1, there are three good substrings ("b", "b", and "bb"). One of them has even length and two of them have odd length.

In example 2, there are six good substrings (i.e. "b", "a", "a", "b", "aa", "baab"). Two of them have even length and four of them have odd length.

In example 3, there are seven good substrings (i.e. "b", "a", "b", "b", "bb", "bab", "babb"). Two of them have even length and five of them have odd length.

Definitions

A substring s[l, r(1 ≤ l ≤ r ≤ n) of string s = s1s2... sn is string slsl + 1... sr.

A string s = s1s2... sn is a palindrome if it is equal to string snsn - 1... s1.

 

Source

 
解题:压缩连续相同的字符成一个!最后剩下的就是a和b相间的串了。我们需要的是压缩后的回文串。当然只能首位相同的子串了。
 
如何在线性时间内找出原串里首位相同的串的个数呢?
 
由于只有两种字符‘a'和’b',还有需要注意一个细节!自然数中,奇数到奇数的闭区间包含奇数个数。奇数到偶数的闭区间包含偶数个数。偶数到偶数的闭区间一定包含偶数个数。
 
长度为奇数的串要么是偶数到偶数,要么是奇数到奇数。同理可以得出长度为偶数的串只能由奇数到偶数 或者 偶数到奇数!
 
比如说某个奇数位置上是a,假设以它作为尾部压缩后回文的串有多少个呢?看首部,首部是奇数位置,那肯定是奇数串,首部是偶数,肯定是偶数串!那到底有多少个奇数串呢?
 
你能在前面找出多少个含a的且是奇数的位置,就能拼出多少个以‘a'结尾的压缩后回文的串!
 
 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cmath>
 5 #include <algorithm>
 6 #include <climits>
 7 #include <vector>
 8 #include <queue>
 9 #include <cstdlib>
10 #include <string>
11 #include <set>
12 #include <stack>
13 #define LL long long
14 #define INF 0x3f3f3f3f
15 using namespace std;
16 LL odd[2],even[2],x,y;
17 char str[100100];
18 int main(){
19     while(~scanf("%s",str)){
20         memset(odd,0,sizeof(odd));
21         memset(even,0,sizeof(even));
22         x = y = 0;
23         for(int i = 0; str[i]; i++){
24             int sb = str[i]-'a';
25             if(i&1){
26                 x += odd[sb];//奇数到奇数是奇数
27                 y += even[sb];//奇数到偶数是偶数
28                 odd[sb]++;
29             }else{
30                 x += even[sb];
31                 y += odd[sb];
32                 even[sb]++;
33             }
34         }
35         printf("%I64d %I64d
",y,x+strlen(str));
36     }
37     return 0;
38 }
View Code
 
原文地址:https://www.cnblogs.com/crackpotisback/p/3906655.html