广义后缀自动机--bzoj3926: [Zjoi2015]诸神眷顾的幻想乡

2024-01-03 13:58

本文主要是介绍广义后缀自动机--bzoj3926: [Zjoi2015]诸神眷顾的幻想乡,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

因为叶子只有 20 20 20个,所以把每个叶子当作根然后把从根开始的所有子串都插入一个广义后缀自动机,这样就可以把所有串取到,每次插入的时候记录一下 f a fa fa是哪个,从那个开始插就好了

这个要求不同子串个数要用 ∑ i = 1 c n t l e n [ i ] − l e n [ f a i ] \sum_{i=1}^{cnt}len[i]-len[fa_i] i=1cntlen[i]len[fai]
因为 f a i fa_i fai i i i的一个后缀,然后 l e n len len记得是最长长度,所以减一下就是新增的不同子串个数

什么时候打 S A M SAM SAM就不用看板子了啊

代码如下:

#include<bits/stdc++.h>
#define N 100005
#define M 2000005
#define LL long long
using namespace std;template<class T>inline void rd(T &x){x=0; short f=1; char c=getchar();while(c<'0' || c>'9') f=c=='-'?-1:1,c=getchar();while(c<='9' && c>='0') x=x*10+c-'0',c=getchar();x*=f;
}int n,m,cnt,head[N],nxt[N<<1],to[N<<1],val[N],deg[N];inline void add(int x,int y){to[++cnt]=y,nxt[cnt]=head[x],head[x]=cnt;to[++cnt]=x,nxt[cnt]=head[y],head[y]=cnt;
}struct SAM{int len[M],ch[M][10],fa[M],cnt;SAM(){cnt=1;}inline int insert(int c,int p){int np=++cnt; len[np]=len[p]+1;while(p&&!ch[p][c]) ch[p][c]=np,p=fa[p];if(!p) fa[np]=1;else{int q=ch[p][c];if(len[p]+1==len[q]) fa[np]=q;else{int nq=++cnt; len[nq]=len[p]+1;memcpy(ch[nq],ch[q],sizeof ch[q]);fa[nq]=fa[q],fa[q]=fa[np]=nq;while(ch[p][c]==q) ch[p][c]=nq,p=fa[p];}} return np;}inline LL solve(){LL ans=0;for(int i=1;i<=cnt;i++) ans+=len[i]-len[fa[i]];return ans;}
}sam;void dfs(int u,int fa,int p){int t=sam.insert(val[u],p);for(int i=head[u],v;i;i=nxt[i])if((v=to[i])!=fa) dfs(v,u,t);
}int main(){rd(n); rd(m); int x,y;for(int i=1;i<=n;i++) rd(val[i]);for(int i=1;i<n;i++){rd(x),rd(y);add(x,y); deg[x]++,deg[y]++;}for(int i=1;i<=n;i++)if(deg[i]==1) dfs(i,0,1);printf("%lld\n",sam.solve());return 0;
}

这篇关于广义后缀自动机--bzoj3926: [Zjoi2015]诸神眷顾的幻想乡的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/565921

相关文章

hdu 3065 AC自动机 匹配串编号以及出现次数

题意: 仍旧是天朝语题。 Input 第一行,一个整数N(1<=N<=1000),表示病毒特征码的个数。 接下来N行,每行表示一个病毒特征码,特征码字符串长度在1—50之间,并且只包含“英文大写字符”。任意两个病毒特征码,不会完全相同。 在这之后一行,表示“万恶之源”网站源码,源码字符串长度在2000000之内。字符串中字符都是ASCII码可见字符(不包括回车)。

POJ 1625 自动机

给出包含n个可见字符的字符集,以下所提字符串均由该字符集中的字符构成。给出p个长度不超过10的字符串,求长为m且不包含上述p个字符串的字符串有多少个。 g++提交 int mat[108][108] ;int matn ;int N ;map<char ,int> to ;//ACconst int maxm = 108 ;const int kin

zoj 3228 ac自动机

给出一个字符串和若干个单词,问这些单词在字符串里面出现了多少次。单词前面为0表示这个单词可重叠出现,1为不可重叠出现。 Sample Input ab 2 0 ab 1 ab abababac 2 0 aba 1 aba abcdefghijklmnopqrstuvwxyz 3 0 abc 1 def 1 jmn Sample Output Case 1 1 1 Case 2

将浮点型算式的中缀表达式转换成后缀表达式并算出式子结果

最近因为需要了解如何将在Win应用程序控制台输入的算式表达式转化成其后缀表达式的算法,所以在网上搜索了一下,看到许多人的程序都只是对应于运算数在0~9的范围内的整型运算式,所以自己就写了一个可以计算浮点型算式的程序,一下是运行时的截图: 式子中的a,b,c是可供用户自行输入的变量。 首先,我先对输入的运算符进行了简单的合法性判断,我的判断代 码如下: //函数的传入参

正规式与有限自动机例题

答案:D 知识点: 正规式 正规集 举例 ab 字符串ab构成的集合 {ab} a|b 字符串a,b构成的集合 {a,b} a^* 由0或者多个a构成的字符串集合 {空,a,aa,aaa,aaaa····} (a|b)^* 所有字符a和b构成的串的集合 {空,a,b,ab,aab,aba,aaab····} a(a|b)^* 以a为首字符的a,b字符串的集

后缀表达式转中缀表达式

假定有后缀表达式1 2 3 + 4 * +5 – ,请将它转化为前缀表达式。 利用表达式树: 1.从左到右扫面后缀表达式,一次一个符号读入表达式。2.如果符号是操作数,那么就建立一个单节点树并将它推入栈中。如果符号是操作符,那么就从栈中弹出两个树T1和T2(T1先弹出)并形成一颗新的树,该树的根就是操作符,它的左、右儿子分别是T2和T1(先出的为右子树,后出的为左子树)。然后将指向这棵新树的指

什么是顶级域名后缀?

在互联网发展的历程中,顶级域名(Top-Level Domain,简称TLD)扮演着至关重要的角色。而这些顶级域名的后缀,则更是成为了整个网络世界的分类标准和识别依据。 顶级域名后缀,通常指位于域名最右端的部分,如".com"、“.org”、".cn"等。它们为下层的二级域名和三级域名提供了一个基础的分类框架,让互联网上的各类网站、组织和个人能够根据自身特点选择合适的域名后缀。 不同类型的顶级

AC自动机 - 多模式串的匹配运用 --- HDU 3065

病毒侵袭持续中  Problem's Link:http://acm.hdu.edu.cn/showproblem.php?pid=3065   Mean:  略 analyse:  AC自动机的运用. 这一题需要将模式串都存储下来,还有就是base的取值一定要弄清楚,由于这题的模式串都是大写字母所以我们可以通过剪枝来加速。 Time complexity:o(n)+o(m

AC自动机 - 多模式串的匹配运用 --- HDU 2896

病毒侵袭 Problem's Link:http://acm.hdu.edu.cn/showproblem.php?pid=2896   Mean:   略 analyse: AC自动机的运用,多模式串匹配。就是有几个细节要注意,在这些细节上卡了半天了。 1)输出的网站编号和最终的病毒网站数不是一样的; 2)next指针要设128,不然会爆栈; 3)同理,char转换为i

后缀数组 - 求最长回文子串 + 模板题 --- ural 1297

1297. Palindrome Time Limit: 1.0 second Memory Limit: 16 MB The “U.S. Robots” HQ has just received a rather alarming anonymous letter. It states that the agent from the competing «Robots Unlim