HDU - 5421:Victor and String (回文树,支持首尾插入新字符)

Sample Input

6
1 a
1 b
2 a
2 c
3
4
8
1 a
2 a
2 a
1 a
3
1 b
3
4

Sample Output

4
5
4
5
11

题意:多组输入,开始字符串为空,支持4中操作: 1,在字符串首加字符; 2,在字符串尾加字符; 3,查询字符串不同本质的回文串个数; 4,查询回文串个数总和

思路:因为支持首尾加入,所以和常规的回文树有些不同。 参考了YYB的博客。 发现首尾互相影响,当且仅当整个字符串是回文串。 其他情况两头正常加即可。

#include<bits/stdc++.h>
#define ll long long
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define rep2(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
const int maxn=100010;
struct PAT
{
    struct node{
        int len,num,fail,son[26];
    }t[maxn];
    int n,tot,s[maxn<<1],L,R,suf,pre; ll ans;
    void init()
    {
        memset(t,0,sizeof(t));
        memset(s,-1,sizeof(s));
        tot=1; L=100000; R=L-1;
        suf=pre=0; ans=0;
        t[1].len=-1; t[0].fail=t[1].fail=1;
    }
    void add(int c,int n,int &last,int op){
        int p=last; s[n]=c;
        while(s[n]!=s[n-op-op*t[p].len]) p=t[p].fail;
        if(!t[p].son[c]){
            int v=++tot,k=t[p].fail;
            while(s[n]!=s[n-op*t[k].len-op]) k=t[k].fail;
            t[v].fail=t[k].son[c];
            t[v].len=t[p].len+2;
            t[v].num=t[t[v].fail].num+1;
            t[p].son[c]=v;
        }
        last=t[p].son[c]; ans+=t[last].num;
        if(t[last].len==R-L+1) suf=pre=last;
    }
}T;
int main()
{
    int N;
    while(~scanf("%d",&N)){
        T.init(); int opt;
        rep(i,1,N){
            scanf("%d",&opt); char s[3];
            if(opt==1){
                scanf("%s",s);
                T.add(s[0]-‘a‘,--T.L,T.pre,-1);
            }
            else if(opt==2){
                scanf("%s",s);
                T.add(s[0]-‘a‘,++T.R,T.suf,1);
            }
            else if(opt==3)
                printf("%d\n",T.tot-1);
            else printf("%lld\n",T.ans);
        }
    }
    return 0;
}

原文地址:https://www.cnblogs.com/hua-dong/p/10355974.html

时间: 2024-10-03 09:04:01

HDU - 5421:Victor and String (回文树,支持首尾插入新字符)的相关文章

HDOJ 5421 Victor and String 回文串自己主动机

假设没有操作1,就是裸的回文串自己主动机...... 能够从头部插入字符的回文串自己主动机,维护两个last点就好了..... 当整个串都是回文串的时候把两个last统一一下 Victor and String Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 524288/262144 K (Java/Others) Total Submission(s): 30    Accepted Submission(s): 9 Probl

HDU 5157 Harry and magic string(回文树)

Harry and magic string Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 223    Accepted Submission(s): 110 Problem Description Harry got a string T, he wanted to know the number of T's disjoint

HDU 6599 I Love Palindrome String (回文树+hash)

题意 找如下子串的个数: (l,r)是回文串,并且(l,(l+r)/2)也是回文串 思路 本来写了个回文树+dfs+hash,由于用了map所以T了 后来发现既然该子串和该子串的前半部分都是回文串,所以该子串的前半部分和后半部分是本质相同的! 于是这个log就去掉了 代码 #include<iostream> #include<cstdio> #include<algorithm> #include<cmath> #include<cstring>

回文树或者回文自动机,及相关例题

回文树简述 在大部分说法中,回文树与回文自动机指的是一个东西: 回文树是对一个字符串,基于自动机思想构建的处理回文问题的树形结构: 回文树是对着一个单串建立的: 于是他主要用于计数(回文子串种类及个数) 基本建立思路是先建立其前缀的回文树,然后每加上一个字符,统计影响: 回文树存在fail指针但一般不承接字符串匹配问题: (回文树大概可以判定一个回文串是不是一个串的子串,但KMP之类的可以做得更好) 构建好的回文树,是这样的: (好难看) 可看出: 存在两个树结构,分别记录奇数|偶数长度的回文:

【HDU5421】Victor and String(回文树)

[HDU5421]Victor and String(回文树) 题面 Vjudge 大意: 你需要支持以下操作: 动态在前端插入一个字符 动态在后端插入一个字符 回答当前本质不同的回文串个数 回答当前回文串个数 题解 回文树前端插入的操作,学一学感觉并不难? 额外维护一下一个前端插入的\(last\) 然后就和后端插入一模一样,前端插入时就是前端插入的\(last\) 唯一会产生的影响的就是当前字符差完后, 发现现在的\(last\)就是整个串,那么就要更新另外一端的\(last\)为当前这一端

HDU - 5157 :Harry and magic string (回文树)

Sample Input aca aaaa Sample Output 3 15 题意: 多组输入,每次给定字符串S(|S|<1e5),求多少对不相交的回文串. 思路:可以用回文树求出以每个位置结尾的回文串数,那么累加得到前缀和: 倒着再做一遍得到每个位置为开头的回文串数,乘正向求出的前缀和即可. #include<bits/stdc++.h> #define ll long long #define rep(i,a,b) for(int i=a;i<=b;i++) #define

hdu 6599 I Love Palindrome String 回文自动机

hdu 6599 I Love Palindrome String 回文自动机 当个回文自动机的模板 题意 给一个串S,求长度为i的"特殊回文串"个数,"特殊回文串"要求是回文串,并且自己的一半也是回文串. 思路 求回文串个数相关,优先考虑使用回文自动机,"特殊回文串"要求是回文串,并且自己的一半也是回文串,显然就是fail树扒出来dfs搞一下,记录dfs路径上有没有长度一半的回文串即可. PS:因为fail指针的意义是最长后缀回文,反过来路径显

HDU 5658 CA Loves Palindromic(回文树)

CA Loves Palindromic Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others) Total Submission(s): 301    Accepted Submission(s): 131 Problem Description CA loves strings, especially loves the palindrome strings. One day

HDU.5394.Trie in Tina Town(回文树)

题目链接 \(Description\) 给定一棵\(Trie\).求\(Trie\)上所有回文串 长度乘以出现次数 的和.这里的回文串只能是从上到下的一条链. 节点数\(n\leq 2\times 10^6\),字符集为a,b,c,d. \(Solution\) 如果不是树,就是回文树模板.对于树,DFS \(x\)的每个儿子的时候都用在\(x\)处的\(las\)即可,也就是按深度存一个\(las\)数组,每次用\(las[dep-1]\)做\(las\)去插入即可.(也可以回溯的时候直接删