zoukankan      html  css  js  c++  java
  • 回文树(统计所有回文串的个数)

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

    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;
    }
  • 相关阅读:
    软件工程结对作业
    软件工程第二次作业
    软件工程第一次作业
    MATLAB安装教程
    实现生成小学四则运算练习题
    结对编程-审查代码
    软件第三次作业
    练习使用Eclipse进行单元测试
    软件工程第一次作业
    Visual Studio Code (vscode)
  • 原文地址:https://www.cnblogs.com/crazyacking/p/4737477.html
Copyright © 2011-2022 走看看