模板—字符串—后缀自动机(后缀自动机+线段树合并求right集合)

Code:

#include <bits/stdc++.h>
using namespace std;
#define N 100010
map <int,int> son[N<<1]; char str[N]; int root[N<<1],pla[N],len;
int tot=1,last=1,pre[N<<1],dis[N<<1],in[N<<1];
namespace Sam
{
void insert(int x,int id)
{
int p=last,np=last=++tot; dis[np]=dis[p]+1,pla[id]=np;
while(p&&!son[p][x]) son[p][x]=np,p=pre[p];
if(!p) {pre[np]=1;return;} int q=son[p][x];
if(dis[q]==dis[p]+1) {pre[np]=q;return;} int nq=++tot;
dis[nq]=dis[p]+1,son[nq]=son[q],pre[nq]=pre[q],pre[q]=pre[np]=nq;
while(p&&son[p][x]==q) son[p][x]=nq,p=pre[p];;
}
}
using namespace Sam;
struct Node {int son[2],size;}node[N<<7];
namespace Tree
{
int cnt;
void pushup(int p) {node[p].size=node[node[p].son[0]].size+node[node[p].son[1]].size;}
void merge(int &x,int y)
{
if(!y) return; if(!x) {x=y;return;}
node[++cnt]=node[x],x=cnt;
merge(node[x].son[0],node[y].son[0]),merge(node[x].son[1],node[y].son[1]),pushup(x);
}
void change(int &p,int l,int r,int x)
{
if(!p) p=++cnt; if(l==r) {node[p].size++;return;}
int mid=(l+r)>>1;
if(x<=mid) change(node[p].son[0],l,mid,x);
else change(node[p].son[1],mid+1,r,x); pushup(p);
}
}
using namespace Tree;
int main()
{
queue <int> q;
scanf("%s",str+1),len=strlen(str+1);
for(int i=1;i<=len;i++) insert(str[i]-'a',i);
for(int i=1;i<=len;i++) change(root[pla[i]],1,len,i);
for(int i=2;i<=tot;i++) in[pre[i]]++;
for(int i=1;i<=tot;i++) if(!in[i]) q.push(i);
while(!q.empty())
{
int p=q.front(); q.pop(),in[pre[p]]--;
if(!in[pre[p]]) q.push(pre[p]);
merge(root[pre[p]],root[p]);
}
}

  

模板—字符串—后缀自动机(后缀自动机+线段树合并求right集合)的更多相关文章

  1. [BJWC2018]Border 的四种求法(后缀自动机+链分治+线段树合并)

    题目描述 给一个小写字母字符串 S ,q 次询问每次给出 l,r ,求 s[l..r] 的 Border . Border: 对于给定的串 s ,最大的 i 使得 s[1..i] = s[|s|-i+ ...

  2. 【codeforces666E】Forensic Examination 广义后缀自动机+树上倍增+线段树合并

    题目描述 给出 $S$ 串和 $m$ 个 $T_i$ 串,$q$ 次询问,每次询问给出 $l$ .$r$ .$x$ .$y$ ,求 $S_{x...y}$ 在 $T_l,T_{l+1},...,T_r ...

  3. CF547E Milk and Friends(AC自动机的fail指针上建主席树 或 广义后缀自动机的parent线段树合并)

    What-The-Fatherland is a strange country! All phone numbers there are strings consisting of lowercas ...

  4. 2019.02.27 bzoj4556: [Tjoi2016&Heoi2016]字符串(二分答案+sam+线段树合并)

    传送门 题意:给一个字符串SSS. 有mmm次询问,每次给四个参数a,b,c,da,b,c,da,b,c,d,问s[a...b]s[a...b]s[a...b]的所有子串和s[x...y]s[x... ...

  5. [NOI2018]你的名字(后缀自动机+线段树合并)

    看到题目名字去补番是种怎么样的体验 我只会 \(68\) 分,打了个暴力.正解看了一会儿,发现跟 \([HEOI2016/TJOI2016]\) 字符串很像,用线段树合并维护 \(endpos\) 集 ...

  6. Codeforces 666E Forensic Examination(广义后缀自动机+线段树合并)

    将所有串(包括S)放一块建SAM.对于询问,倍增定位出该子串所在节点,然后要查询的就是该子串在区间内的哪个字符串出现最多.可以线段树合并求出该节点在每个字符串中的出现次数. #include<b ...

  7. 洛谷P4770 [NOI2018]你的名字 [后缀自动机,线段树合并]

    传送门 思路 按照套路,直接上后缀自动机. 部分分:\(l=1,r=|S|\) 首先把\(S\)和\(T\)的后缀自动机都建出来. 考虑枚举\(T\)中的右端点\(r\),查询以\(r\)结尾的串最长 ...

  8. CF1037H Security 后缀自动机 + right集合线段树合并 + 贪心

    题目描述: 给定一个字符串 $S$ 给出 $Q$ 个操作,给出 $L,R,T$,求出字典序最小的 $S_{1}$ 为 $S[L...R]$的子串,且 $S_{1}$ 的字典序严格大于 $T$. 输出这 ...

  9. HDU4641 K-string(后缀自动机+线段树合并)

    先考虑没有动态加字符怎么做.计算每个节点的贡献,当|right|>=k时将len-lenfa计入即可. 动态加字符后,这个东西难以用LCT维护.于是考虑离线.建完SAM后,容易发现每个节点在时间 ...

随机推荐

  1. Visual Studio 提示某个dll文件(已在Microsoft Visual Studio 外对该文件进行了修改,是否重新加载它)

    如题: Visual Studio 提示某个dll文件(已在Microsoft Visual Studio 外对该文件进行了修改,是否重新加载它) 如果选择“是”,那恭喜你,第二次生成的时候,引用这个 ...

  2. Cookies 、 Session 和 token 的区别

    这篇文章写的 Cookies 和 Session的区别 比较详细,也很好理解,可以学习下:https://blog.csdn.net/axin66ok/article/details/6175522 ...

  3. java初学4

    1.interface接口 (1)[修饰符] interface 接口名 extends 父接口1,父接口2....        •没有构造方法,不能实例化;        •接口只能继承接口,不能 ...

  4. 聊聊、Mybatis XML

    引入相应的依赖包 <dependency><groupId>org.mybatis</groupId><artifactId>mybatis-sprin ...

  5. 201621123033 《Java程序设计》第1周学习总结

    1. 本周学习总结 · jdk.jre.jvm的含义及相关概念(具体见下文回答) · 会使用记事本及简单编辑器编写Java程序,理解javac和java命令的含义(具体见下文回答) · java与C语 ...

  6. 《c程序设计语言》读书笔记-4.13-递归版本reverse函数

    #include <stdio.h> #include <math.h> #include <stdlib.h> #include <string.h> ...

  7. linux mint 自动挂载windows的D盘和E盘

    终端敲udisksctl mount -p block_devices/sda后双击tab键补全分区,如下:    如我的E盘是sda6,执行     udisksctl mount -p block ...

  8. JAVA中GC时finalize()方法是不是一定会被执行?

    在回答上面问题之前,我们一定要了解JVM在进行垃圾回收时的机制,首先: 一.可达性算法  要知道对象什么时候死亡,我们需要先知道JVM的GC是如何判断对象是可以回收的.JAVA是通过可达性算法来来判断 ...

  9. 埃及分数问题_迭代加深搜索_C++

    一.题目背景 http://codevs.cn/problem/1288/ 给出一个真分数,求用最少的1/a形式的分数表示出这个真分数,在数量相同的情况下保证最小的分数最大,且每个分数不同. 如 19 ...

  10. 灰姑娘的水晶鞋(NOIP模拟赛Round 7)

    [问题描述] 传说中的水晶鞋有两种颜色:左边的水晶鞋是红色,右边的是蓝色,据说穿上它们会有神奇的力量. 灰姑娘要找到她所有的n双水晶鞋,它们散落在一条数轴的正半轴上,坐标各不相同,每双水晶鞋还有一个权 ...