bzoj4516 [Sdoi2016]生成魔咒

网友投稿 875 2022-08-29

bzoj4516 [Sdoi2016]生成魔咒

bzoj4516 [Sdoi2016]生成魔咒

​​ Description 魔咒串由许多魔咒字符组成,魔咒字符可以用数字表示。例如可以将魔咒字符 1、2 拼凑起来形成一个魔咒串 [1,2]。 一个魔咒串 S 的非空字串被称为魔咒串 S 的生成魔咒。 例如 S=[1,2,1] 时,它的生成魔咒有 [1]、[2]、[1,2]、[2,1]、[1,2,1] 五种。S=[1,1,1] 时,它的生成魔咒有 [1]、 [1,1]、[1,1,1] 三种。最初 S 为空串。共进行 n 次操作,每次操作是在 S 的结尾加入一个魔咒字符。每次操作后都 需要求出,当前的魔咒串 S 共有多少种生成魔咒。 Input 第一行一个整数 n。 第二行 n 个数,第 i 个数表示第 i 次操作加入的魔咒字符。 1≤n≤100000。,用来表示魔咒字符的数字 x 满足 1≤x≤10^9 Output 输出 n 行,每行一个数。第 i 行的数表示第 i 次操作后 S 的生成魔咒数量 Sample Input 7 1 2 3 3 3 1 2 Sample Output 1 3 6 9 12 17 22 HINT Source 鸣谢Menci上传 每个节点对应若干个子串,所有节点代表的所有子串本质不同,节点i代表的子串个数为最长的长度减去par树上最长的长度

#include#include#include#define N 220000#define ll long long using namespace std;inline char gc(){ static char now[1<<16],*S,*T; if (T==S){T=(S=now)+fread(now,1,1<<16,stdin);if (T==S) return EOF;} return *S++;}inline int read(){ int x=0,f=1;char ch=gc(); while(ch<'0'||ch>'9') {if (ch=='-') f=-1;ch=gc();} while(ch<='9'&&ch>='0') x=(x<<3)+(x<<1)+ch-'0',ch=gc(); return x*f;}map ch[N];ll ans;int fa[N],last=1,cnt=1,root=1,len[N];inline void insert1(int x){ int np=++cnt,p=last;fa[np]=p;len[np]=len[p]+1; for (;p&&!ch[p][x];p=fa[p]) ch[p][x]=np; if (!p) fa[np]=root;else{ int q=ch[p][x];if (len[p]+1==len[q]) fa[np]=q;else{ int nq=++cnt;ch[nq]=ch[q];fa[nq]=fa[q];fa[np]=fa[q]=nq; len[nq]=len[p]+1;for (;p&&ch[p][x]==q;p=fa[p]) ch[p][x]=nq; } }last=np;ans+=len[np]-len[fa[np]];}int main(){// freopen("bzoj4516.in","r",stdin); for (register int i=read();i;--i) insert1(read()),printf("%lld\n",ans); return 0;}

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Redis缓存穿透、缓存击穿、缓存雪崩的原理和解决办法
下一篇:SEM1 PSYCHOLOGY LEC2
相关文章

 发表评论

暂时没有评论,来抢沙发吧~