回文树(统计所有回文串的个数) - MCCME 1750 Подпалиндромы

本文涉及的产品
实时计算 Flink 版,5000CU*H 3个月
简介: Подпалиндромы  Problem's Link:  http://informatics.mccme.ru//mod/statements/view.php?chapterid=1750#   Mean:  给你一个长度不超过1e5的字符串,要统计总共有多少个回文串。

Подпалиндромы 

Problem's Link:  http://informatics.mccme.ru//mod/statements/view.php?chapterid=1750#


 

Mean: 

给你一个长度不超过1e5的字符串,要统计总共有多少个回文串。(第一次刷俄语题,还好有google翻译)。

analyse:

如果题目说是不同回文串的话,这题就是一个裸的回文树。

由于要求所有子串的回文数,所以我们在插入的时候还需要使用suffixLink往上走统计答案。

Time complexity: O(N)

 

Source code: 

/*
* this code is made by crazyacking
* Verdict: Accepted
* Submission Date: 2015-08-17-19.13
* Time: 0MS
* Memory: 137KB
*/
#include <queue>
#include <cstdio>
#include <set>
#include <string>
#include <stack>
#include <cmath>
#include <climits>
#include <map>
#include <cstdlib>
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
#define  LL long long
#define  ULL unsigned long long
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;
      } 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()
{
      gets(s);
      initTree();
      for( int i = 0;s [ i ]; i ++)
      {
            addLetter( i);
            ans += tree [ suff ]. num;
      } cout << ans << endl;
      return 0;
}

 

相关实践学习
基于Hologres轻松玩转一站式实时仓库
本场景介绍如何利用阿里云MaxCompute、实时计算Flink和交互式分析服务Hologres开发离线、实时数据融合分析的数据大屏应用。
Linux入门到精通
本套课程是从入门开始的Linux学习课程,适合初学者阅读。由浅入深案例丰富,通俗易懂。主要涉及基础的系统操作以及工作中常用的各种服务软件的应用、部署和优化。即使是零基础的学员,只要能够坚持把所有章节都学完,也一定会受益匪浅。
目录
相关文章
|
算法 测试技术 C#
C++前缀和算法的应用:统计得分小于K的子数组数目
C++前缀和算法的应用:统计得分小于K的子数组数目
|
2月前
|
5月前
|
存储
2559. 统计范围内的元音字符串数(前缀和) o(n)时间复杂度
2559. 统计范围内的元音字符串数(前缀和) o(n)时间复杂度
|
7月前
|
算法 测试技术 C#
【线段树】2276. 统计区间中的整数数目
【线段树】2276. 统计区间中的整数数目
|
7月前
|
算法 测试技术 C#
【最大公约数 调和级数】2183.统计可以被 K 整除的下标对数目
【最大公约数 调和级数】2183.统计可以被 K 整除的下标对数目
|
7月前
|
Serverless
leetcode2719. 统计整数数目
leetcode2719. 统计整数数目
49 0
|
7月前
|
存储 C语言 Windows
Day5 统计回文、连续最大和
Day5 统计回文、连续最大和
55 0
LeetCode-2044 统计按位或能得到最大值子集的数目
LeetCode-2044 统计按位或能得到最大值子集的数目
LeetCode 1684. 统计一致字符串的数目
给你一个由不同字符组成的字符串 allowed 和一个字符串数组 words 。
86 0