生成魔咒

Time Limit: 10 Sec  Memory Limit: 128 MB
[Submit][Status][Discuss]

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 次操作加入的魔咒字符。

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

  1≤n≤100000

Main idea

  询问在加入每一个字符后当前有多少个本质不同的子串。

Solution

  直接用SAM,根据SAM的性质,每次增多的子串个数就是len[New] - len[fa[New]]

Code

  1. #include<iostream>
  2. #include<string>
  3. #include<algorithm>
  4. #include<cstdio>
  5. #include<cstring>
  6. #include<cstdlib>
  7. #include<cmath>
  8. #include<map>
  9. using namespace std;
  10. typedef long long s64;
  11.  
  12. const int ONE = ;
  13. const int INF = ;
  14.  
  15. int n,x;
  16. s64 Ans;
  17.  
  18. int get()
  19. {
  20. int res=,Q=;char c;
  21. while( (c=getchar())< || c> )
  22. if(c=='-')Q=-;
  23. res=c-;
  24. while( (c=getchar())>= && c<= )
  25. res=res*+c-;
  26. return res*Q;
  27. }
  28.  
  29. struct SAM
  30. {
  31. map <int, int> a[ONE];
  32. int len[ONE], fa[ONE];
  33. int last, cnt;
  34. SAM() {last = cnt = ;}
  35. void Add(int c)
  36. {
  37. int x = last, New = last = ++cnt;
  38. len[New] = len[x] + ;
  39. while(x && !a[x][c]) a[x][c] = New, x = fa[x];
  40. if(!x) {fa[New] = ; Ans += len[New] - len[fa[New]]; return;}
  41.  
  42. int q = a[x][c];
  43. if(len[x] + == len[q]) fa[New] = q;
  44. else
  45. {
  46. int Nq = ++cnt; len[Nq] = len[x] + ;
  47. a[Nq] = a[q];
  48. fa[Nq] = fa[q];
  49. fa[New] = fa[q] = Nq;
  50. while(a[x][c] == q) a[x][c] = Nq, x = fa[x];
  51. }
  52. Ans += len[New] - len[fa[New]];
  53. }
  54. }S;
  55.  
  56. int main()
  57. {
  58. n = get();
  59. while(n--)
  60. {
  61. x = get();
  62. S.Add(x);
  63. printf("%lld\n", Ans);
  64. }
  65.  
  66. }

【BZOJ4516】【SDOI2016】生成魔咒 [SAM]的更多相关文章

  1. bzoj4516: [Sdoi2016]生成魔咒 sam

    题意:每次插入一个数字,查询本质不同的子串有多少个 题解:sam,数字很大,ch数组用map来存,每次ins之后查询一下新建点表示多少个本质不同的子串(l[np]-l[fa[np]]) /****** ...

  2. BZOJ4516: [Sdoi2016]生成魔咒 后缀自动机

    #include<iostream> #include<cstdio> #include<cstring> #include<queue> #inclu ...

  3. [Sdoi2016]生成魔咒[SAM or SA]

    4516: [Sdoi2016]生成魔咒 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1017  Solved: 569[Submit][Statu ...

  4. [bzoj4516][Sdoi2016]生成魔咒——后缀自动机

    Brief Description 魔咒串由许多魔咒字符组成,魔咒字符可以用数字表示.例如可以将魔咒字符 1.2 拼凑起来形成一个魔咒串 [1,2]. 一个魔咒串 S 的非空字串被称为魔咒串 S 的生 ...

  5. BZOJ4516 [Sdoi2016]生成魔咒 【后缀自动机】

    题目 魔咒串由许多魔咒字符组成,魔咒字符可以用数字表示.例如可以将魔咒字符 1.2 拼凑起来形成一个魔咒串 [1,2]. 一个魔咒串 S 的非空字串被称为魔咒串 S 的生成魔咒. 例如 S=[1,2, ...

  6. BZOJ4516: [Sdoi2016]生成魔咒

    果然SA比SAM+map快~加了fread目前rank1. 首先这是SAM裸题,然而SA求本质不同子串个数也很容易.考虑倒着建SA,这样没错加一个字符就变成加一个后缀,其他后缀都不变,那么i的答案就是 ...

  7. BZOJ4516 SDOI2016生成魔咒(后缀数组+平衡树)

    一个字符串本质不同的子串数量显然是总子串数减去所有height值.如果一个个往里加字符的话,每次都会改动所有后缀完全没法做.但发现如果从后往前加的话,每次只会添加一个后缀.于是我们把字符串倒过来,每次 ...

  8. 2018.12.23 bzoj4516: [Sdoi2016]生成魔咒(后缀自动机)

    传送门 samsamsam入门题. 题意简述:给出一个串让你依次插入字符,求每次插入字符之后不同子串的数量. 显然每次的变化量只跟新出现的nnn个后缀有关系,那么显然就是maxlenp−maxlenl ...

  9. bzoj千题计划283:bzoj4516: [Sdoi2016]生成魔咒(后缀数组)

    http://www.lydsy.com/JudgeOnline/problem.php?id=4516 考虑在后面新加一个字母产生的影响 假设是第i个 如果不考虑重复,那么会增加i个不同的字符串 考 ...

  10. BZOJ4516: [Sdoi2016]生成魔咒(后缀数组 set RMQ)

    题意 题目链接 Sol 毒瘤SDOI 终于有一道我会做的题啦qwq 首先,本质不同的子串的个数 $ = \frac{n(n + 1)}{2} - \sum height[i]$ 把原串翻转过来,每次就 ...

随机推荐

  1. Spark GraphX 2

    顶点:VertexRDD   边:EdgeRDD.Edge.EdgeDirection   Triplet:EdgeTriplet   存储:PartitionStrategy 通常的存储方式有两种: ...

  2. 从电梯问题,看c和c++之间的区别(有点懂了)错觉错觉

    磕磕碰碰的也相继用c和c++构造了不少的电梯了.虽然对自我的表现不满意,但是总体来说还是有一定的收获的,对于c和c++之间的区别感觉也摸到了一点点门道了... 用c语言构造电梯的步骤: 第一步: 分析 ...

  3. 深入理解Java对象序列化(转载)

    原文地址:http://developer.51cto.com/art/201202/317181.htm 1. 什么是Java对象序列化 Java平台允许我们在内存中创建可复用的Java对象,但一般 ...

  4. lintcode-33-N皇后问题

    33-N皇后问题 n皇后问题是将n个皇后放置在n*n的棋盘上,皇后彼此之间不能相互攻击. 给定一个整数n,返回所有不同的n皇后问题的解决方案. 每个解决方案包含一个明确的n皇后放置布局,其中" ...

  5. Xcode常见警告和错误

    Xcode 升级后,常常遇到的遇到的警告.错误,解决方法 从sdk3.2.5升级到sdk 7.1中间废弃了很多的方法,还有一些逻辑关系更加严谨了.1,警告:“xoxoxoxo”  is depreca ...

  6. OSG学习:位置变换节点示例

    osg::PositionAttitudeTransform节点. #include <osgViewer\Viewer> #include <osg\Node> #inclu ...

  7. 重要的几个按键Tab Ctrl+c Ctrl+d

    1.Tab按键具有命令补齐和档案补齐的功能,重点是可以避免我们打错命令或者文件名,但是Tab按键在不同的地方输入会有不同的结果 试着多按几下,或者连按两次相信你会发现新大陆 a.Tab接在一串指令的第 ...

  8. PHP中如何使用Redis接管文件存储Session详解

    https://www.jb51.net/article/151580.htm 前言 php默认使用文件存储session,如果并发量大,效率会非常低.而redis对高并发的支持非常好,可以利用red ...

  9. 阻塞 , 非阻塞 , 同步 ,异步 , I/O模型

    •阻塞,非阻塞:进程/线程要访问的数据是否就绪,进程/线程是否需要等待: •同步,异步:访问数据的方式,同步需要主动读写数据,在读写数据的过程中还是会阻塞:异步只需要I/O操作完成的通知,并不主动读写 ...

  10. Mysql查询优化从入门到跑路(三)查询的基本操作

    查询的基本操作 1.选择操作 对应的是限制条件,操作对象是二维表的行.     优化方式:选择操作下推     目的:尽量减少连接操作前的元租数,使得中间临时关系尽量少(元祖数少,连接得到的元组数就少 ...