Codeforces 451D Count Good Substrings (组合数)

题意

给出一个只有a和b的串求有多少个子串满足删去连续的重复字母之后是一个回文串,输出分为奇数长度和偶数长度的。

思路

只有两个字母这是个很重要的条件,这样的话一个子串只需要头和尾相同就可以删成一个回文串了。
那就分别讨论一下就可以了:
=C(2oddnumofa)+C(2oddnumofb)+C(2evennumofa)+C(2evennumofb)
=oddnumofaevennumofa+oddnumofbevennumofa

代码

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <list>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
using namespace std;
#define LL long long
#define lowbit(x) ((x)&(-x))
#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1|1
#define MP(a, b) make_pair(a, b)
const int INF = 0x3f3f3f3f;
const int MOD = 1000000007;
const int maxn = 1e5 + 10;
const double eps = 1e-8;
const double PI = acos(-1.0);
typedef pair<int, int> pii;

char s[100010];

LL cal(LL x)
{
    return x * (x - 1) / 2;
}

int main()
{
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    scanf("%s", s + 1);
    int len = strlen(s + 1);
    LL odda = 0, oddb = 0;
    LL evena = 0, evenb = 0;
    for (int i = 1; i <= len; i++)
    {
        if (s[i] == 'a')
            if (i & 1) odda++;
            else evena++;
        else
            if (i & 1) oddb++;
            else evenb++;
    }
    LL ans1 = cal(odda) + cal(oddb) + cal(evena) + cal(evenb) + len;
    LL ans2 = odda * evena + oddb * evenb;
    printf("%lld %lld\n", ans2, ans1);
    return 0;
}

你可能感兴趣的:(codeforces)