HIHOcoder 1445 后缀自动机二·重复旋律5

思路

题目要求求出有多少个不同的子串出现

因为后缀自动机每个状态存储的是连续的后缀,所以一个状态对应的子串个数就是maxlen[x]-minlen[x]+1

代码

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <iostream>
using namespace std;
const int MAXN = 1000100*2;
int maxlen[MAXN],minlen[MAXN],trans[MAXN][26],suflink[MAXN],cnt=0,n=0;
char s[MAXN];
int new_st(int _maxlen,int _minlen,int *_trans,int _suflink){
    ++cnt;
    maxlen[cnt]=_maxlen;
    minlen[cnt]=_minlen;
    if(_trans)
        for(int i=0;i<26;i++)
            trans[cnt][i]=_trans[i];
    suflink[cnt]=_suflink;
    return cnt;
}
int add_len(int u,int c){
    int z=new_st(maxlen[u]+1,0,NULL,0);
    while(u&&(!trans[u][c])){
        trans[u][c]=z;
        u=suflink[u];
    }
    if(u==0){
        suflink[z]=1;
        minlen[z]=1;
        return z;
    }
    int v=trans[u][c];
    if(maxlen[u]+1==maxlen[v]){
        suflink[z]=v;
        minlen[z]=maxlen[v]+1;
        return z;
    }
    int y=new_st(maxlen[u]+1,0,trans[v],suflink[v]);
    suflink[v]=suflink[z]=y;
    minlen[v]=minlen[z]=maxlen[y]+1;
    while(u&&trans[u][c]==v){
        trans[u][c]=y;
        u=suflink[u];
    }
    minlen[y]=maxlen[suflink[y]]+1;
    return z;
}
int main(){
    scanf("%s",s+1);
    n=strlen(s+1);
    int pre=1;
    cnt=1;
    long long ans=0;
    for(int i=1;i<=n;i++)
        pre=add_len(pre,s[i]-'a');
    for(int i=2;i<=cnt;i++){
        ans+=maxlen[i]-minlen[i]+1;
        // printf("%d %d %d %d\n",i,suflink[i],minlen[i],maxlen[i]);
    }
    printf("%lld\n",ans);
    return 0;
}

原文地址:https://www.cnblogs.com/dreagonm/p/10468727.html

时间: 2024-08-05 08:26:13

HIHOcoder 1445 后缀自动机二·重复旋律5的相关文章

hiho一下第128周 后缀自动机二&#183;重复旋律5

#1445 : 后缀自动机二·重复旋律5 时间限制:10000ms 单点时限:2000ms 内存限制:512MB 描述 小Hi平时的一大兴趣爱好就是演奏钢琴.我们知道一个音乐旋律被表示为一段数构成的数列. 现在小Hi想知道一部作品中出现了多少不同的旋律? 解题方法提示 输入 共一行,包含一个由小写字母构成的字符串.字符串长度不超过 1000000. 输出 一行一个整数,表示答案. 样例输入 aab 样例输出 5 解题方法提示 小Hi:本周的题目其实就是给定一个字符串S,要求出S的所有不同子串的数

hihocoder #1465 : 后缀自动机五&#183;重复旋律8

#1465 : 后缀自动机五·重复旋律8 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi平时的一大兴趣爱好就是演奏钢琴.我们知道一段音乐旋律可以被表示为一段数构成的数列. 小Hi发现旋律可以循环,每次把一段旋律里面最前面一个音换到最后面就成为了原旋律的“循环相似旋律”,还可以对“循环相似旋律”进行相同的变换能继续得到原串的“循环相似旋律”. 小Hi对此产生了浓厚的兴趣,他有若干段旋律,和一部音乐作品.对于每一段旋律,他想知道有多少在音乐作品中的子串(重复便多

hihocoder #1407 : 后缀数组二&#183;重复旋律2

#1407 : 后缀数组二·重复旋律2 Time Limit:5000ms Case Time Limit:1000ms Memory Limit:256MB 描述 小Hi平时的一大兴趣爱好就是演奏钢琴.我们知道一个音乐旋律被表示为长度为 N 的数构成的数列.小Hi在练习过很多曲子以后发现很多作品自身包含一样的旋律. 旋律可以表示为一段连续的数列,相似的旋律在原数列不可重叠,比如在1 2 3 2 3 2 1 中 2 3 2 出现了一次,2 3 出现了两次,小Hi想知道一段旋律中出现次数至少为两次

hihocoder #1449 : 后缀自动机三&#183;重复旋律6

#1449 : 后缀自动机三·重复旋律6 时间限制:15000ms 单点时限:3000ms 内存限制:512MB 描述 小Hi平时的一大兴趣爱好就是演奏钢琴.我们知道一个音乐旋律被表示为一段数构成的数列. 现在小Hi想知道一部作品中所有长度为K的旋律中出现次数最多的旋律的出现次数.但是K不是固定的,小Hi想知道对于所有的K的答案. 解题方法提示 × 解题方法提示 小Hi:上次我们已经学习了后缀自动机了,今天我们再来解决一个用到后缀自动机的问题. 小Ho:好!那我们开始吧! 小Hi:现在我们要对K

hihocoder #1457 : 后缀自动机四&#183;重复旋律7

#1457 : 后缀自动机四·重复旋律7 时间限制:15000ms 单点时限:3000ms 内存限制:512MB 描述 小Hi平时的一大兴趣爱好就是演奏钢琴.我们知道一段音乐旋律可以被表示为一段数构成的数列. 神奇的是小Hi发现了一部名字叫<十进制进行曲大全>的作品集,顾名思义,这部作品集里有许多作品,但是所有的作品有一个共同特征:只用了十个音符,所有的音符都表示成0-9的数字. 现在小Hi想知道这部作品中所有不同的旋律的“和”(也就是把串看成数字,在十进制下的求和,允许有前导0).答案有可能

hiho一下第129周 后缀自动机二&#183;重复旋律6

后缀自动机三·重复旋律6 时间限制:15000ms 单点时限:3000ms 内存限制:512MB 描述 小Hi平时的一大兴趣爱好就是演奏钢琴.我们知道一个音乐旋律被表示为一段数构成的数列. 现在小Hi想知道一部作品中所有长度为K的旋律中出现次数最多的旋律的出现次数.但是K不是固定的,小Hi想知道对于所有的K的答案. 解题方法提示 输入 共一行,包含一个由小写字母构成的字符串S.字符串长度不超过 1000000. 输出 共Length(S)行,每行一个整数,表示答案. 样例输入 aab 样例输出

hihocoder 后缀自动机二&#183;重复旋律5

求不同子串个数 裸的后缀自动机 1 #include<cstring> 2 #include<cmath> 3 #include<iostream> 4 #include<algorithm> 5 #include<cstdio> 6 7 #define ll long long 8 #define N 2000007 9 using namespace std; 10 inline int read() 11 { 12 int x=0,f=1;

hihocoder1445 后缀自动机二&#183;重复旋律5

传送门:http://hihocoder.com/problemset/problem/1445 [题解] 大概看了一天的后缀自动机,总算懂了一些 这篇文章写的非常好,诚意安利:Suffix Automaton Tutorial - Hunt Zhan 我就是看了这个大概懂了. 整个过程大概是:每次插入一个state可能会分裂原有的state的transition,就维护这个transition即可. 要用par[x]记录suffix-link是谁. 过程中可以不用记录minlen,因为$min

hihocoder 1457 后缀自动机四&#183;重复旋律7 求不同子串的和

描述 小Hi平时的一大兴趣爱好就是演奏钢琴.我们知道一段音乐旋律可以被表示为一段数构成的数列. 神奇的是小Hi发现了一部名字叫<十进制进行曲大全>的作品集,顾名思义,这部作品集里有许多作品,但是所有的作品有一个共同特征:只用了十个音符,所有的音符都表示成0-9的数字. 现在小Hi想知道这部作品中所有不同的旋律的“和”(也就是把串看成数字,在十进制下的求和,允许有前导0).答案有可能很大,我们需要对(10^9 + 7)取摸. 解题方法提示 × 解题方法提示 小Hi:我们已经学习了后缀自动机,今天