Cod sursa(job #1736246)

Utilizator AlexNiuclaeNiculae Alexandru Vlad AlexNiuclae Data 1 august 2016 14:33:27
Problema PScPld Scor 30
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.31 kb
///palindromic tree
/*#include <bits/stdc++.h>

using namespace std;

const int nmax = 1e6 + 10;

struct Tree
{
    int number , link , length;
    int letter[26];
};

int n;
long long ans;
char s[nmax];

int nrNodes , actNode;

Tree tree[nmax];

void initTree()
{
    nrNodes = 2; actNode = 2;
    tree[1].length = -1; tree[1].link = 1;
    tree[2].length = 0; tree[2].link = 1;
}

int newPalindromes(int pos)
{
    int act = actNode;

    for (act = actNode; ; act = tree[act].link)
    {
        int actL = tree[act].length;
        if (pos - actL - 1 > 0 && s[pos-actL-1] == s[pos])
            break;
    }

    if (tree[act].letter[s[pos]-'a'])
    {
        actNode = tree[act].letter[s[pos]-'a'];
        return tree[actNode].number;
    }

    nrNodes++; actNode = nrNodes;
    tree[act].letter[s[pos]-'a'] = nrNodes;
    tree[nrNodes].length = tree[act].length + 2;

    if (act == 1)
    {
        tree[nrNodes].link = 2;
        return tree[nrNodes].number = 1;
    }

    for (act = tree[act].link ; ; act = tree[act].link)
    {
        int actL = tree[act].length;
        if (pos - actL - 1 > 0 && s[pos-actL-1] == s[pos])
            break;
    }

    act = tree[act].letter[s[pos]-'a'];

    tree[nrNodes].link = act;
    return tree[nrNodes].number = 1 + tree[act].number;
}

int main()
{
    freopen("pscpld.in","r",stdin);
    freopen("pscpld.out","w",stdout);

    gets(s + 1);
    n = strlen(s + 1);

    initTree();
    for (int i = 1; i <= n; ++i)
        ans += newPalindromes(i);

    printf("%lld\n", ans);

    return 0;
}
*/

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <string>
#include <utility>
#include <cstring>
#include <cassert>
#include <cmath>
#include <stack>
#include <queue>

using namespace std;

const int MAXN = 105000;

struct node {
	int next[26];
	int len;
	int sufflink;
	int num;
};

int len;
char s[MAXN];
node tree[MAXN];
int num; 			// node 1 - root with len -1, node 2 - root with len 0
int suff; 			// max suffix palindrome
long long ans;

bool addLetter(int pos) {
	int cur = suff, curlen = 0;
	int let = s[pos] - 'a';

	while (true) {
		curlen = tree[cur].len;
		if (pos - 1 - curlen >= 0 && s[pos - 1 - curlen] == s[pos])
			break;
		cur = tree[cur].sufflink;
	}
	if (tree[cur].next[let]) {
		suff = tree[cur].next[let];
		return false;
	}

	num++;
	suff = num;
	tree[num].len = tree[cur].len + 2;
	tree[cur].next[let] = num;

	if (tree[num].len == 1) {
		tree[num].sufflink = 2;
		tree[num].num = 1;
		return true;
	}

	while (true) {
		cur = tree[cur].sufflink;
		curlen = tree[cur].len;
		if (pos - 1 - curlen >= 0 && s[pos - 1 - curlen] == s[pos]) {
			tree[num].sufflink = tree[cur].next[let];
			break;
		}
	}

	tree[num].num = 1 + tree[tree[num].sufflink].num;

	return true;
}

void initTree() {
	num = 2; suff = 2;
	tree[1].len = -1; tree[1].sufflink = 1;
	tree[2].len = 0; tree[2].sufflink = 1;
}

int main() {
	freopen("pscpld.in", "r", stdin);
	freopen("pscpld.out", "w", stdout);

	gets(s);
	len = strlen(s);

	initTree();

	for (int i = 0; i < len; i++) {
		addLetter(i);
		ans += tree[suff].num;
	}

	printf("%lld\n", ans);

	return 0;
}