Pagini recente » Cod sursa (job #241382) | Cod sursa (job #1606928) | Cod sursa (job #1374818) | Cod sursa (job #1382634) | Cod sursa (job #1427085)
#include <bits/stdc++.h>
using namespace std;
const int MAX_LEN = 600000;
const int SIGMA = 26;
class PalindromicTree
{
public:
class Node
{
public:
int next[SIGMA];
int length;
int suffixLink;
int countPalindromes;
Node() : length(0), suffixLink(0), countPalindromes(0)
{
for (int i = 0; i < SIGMA; ++i)
this->next[i] = 0;
}
};
Node Tree[MAX_LEN + 2 + 1];
char String[MAX_LEN + 1];
int countNodes;
int lastNode;
int lengthString;
PalindromicTree() : countNodes(2), lastNode(2), lengthString(0)
{
Tree[1].length = -1; Tree[1].suffixLink = 1;
Tree[2].length = 0; Tree[2].suffixLink = 1;
}
bool addLetter(int c)
{
String[ lengthString++ ] = c;
int node = lastNode;
int lg = 0;
while (true)
{
lg = Tree[node].length;
if (lengthString - 2 - lg >= 0 && String[lengthString - 2 - lg] == String[lengthString - 1])
break;
node = Tree[node].suffixLink;
}
if (Tree[node].next[c] != 0)
{
lastNode = Tree[node].next[c];
return false;
}
lastNode = ++countNodes;
Tree[lastNode].length = Tree[node].length + 2;
Tree[node].next[c] = lastNode;
if (Tree[lastNode].length == 1)
{
Tree[lastNode].suffixLink = 2;
Tree[lastNode].countPalindromes = 1;
return true;
}
node = Tree[node].suffixLink;
while (true)
{
lg = Tree[node].length;
if (lengthString - 2 - lg >= 0 && String[lengthString - 2 - lg] == String[lengthString - 1])
break;
node = Tree[node].suffixLink;
}
Tree[lastNode].suffixLink = Tree[node].next[c];
Tree[lastNode].countPalindromes = Tree[ Tree[lastNode].suffixLink ].countPalindromes + 1;
return true;
}
int countPalindromes()
{
return Tree[lastNode].countPalindromes;
}
};
char str[MAX_LEN];
PalindromicTree P;
int main()
{
freopen("pscpld.in", "r", stdin);
freopen("pscpld.out", "w", stdout);
scanf("%s", str);
int n = strlen(str);
long long sol = 0;
for (int i = 0; i < n; ++i)
{
P.addLetter(str[i] - 'a');
sol += P.countPalindromes();
}
cout << sol << "\n";
return 0;
}