原文链接http://www.cnblogs.com/zhouzhendong/p/9010851.html

题目传送门 - Codeforces 316G3

题意

  给定一个母串$s$,问母串$s$有多少本质不同的子串$t$是“好”的。

  一个字符串$t$是好的,仅当$t$满足了所有的$n$个条件。

  第$i$个条件用一个三元组$(p_i,L_i,R_i)$来描述。

  其中$p_i$为一个字符串,$L_i,R_i$为整数,且$L_i\leq R_i$。

  仅当字符串$t$在$p_i$中出现次数在$L_i$到$R_i$之间时,它是"好"的。

  $|s|,|p_i|\leq 5\times 10^4,n\leq 10$

题解

  考虑把输入的$n+1$个字符串用特殊字符隔开,并练成一个串。

  为了方便,我们将母串$s$放在第一个,$n$条规则中的字符串依次连续。

  我们定义数组$tot[i][j]$表示后缀自动机状态$i$的$Right$集合中有多少个位置处于第$j$个串。其中母串为第$0$个串,$p_i$为第$i$个串。

  这个可以通过基数排序+$dp$来搞定。

  然后我们分状态统计。

  对于状态$i$,如果$tot[i][0]=0$,那么说明这个状态所表示的一些串不存在于母串中,所以可以跳过。

  否则$tot[i][0]>0$,这个状态所表示的一些串存在于母串中。由于母串中没有特殊的字符,所以这个状态所表示的一些串也没有特殊字符,所以,对于已经得到的计数$tot[i][1\cdot n]$中也没有统计到包含特殊字符的子串。

  如果当前状态被计入,那么需要满足所有的$n$个条件,即$\forall 1\leq j\leq n,\ \ L_j\leq tot[i][j]\leq R_j$。当前状态包含的本质不同的串的个数显然为$Max(i)-Min(i)+1=Max(i)-Max(fa(i))$。加到答案里就可以了。

代码

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=550005;
int n,m,L[15],R[15];
int size=1,root=1,last=1;
int tax[N<<1],id[N<<1];
LL tot[N<<1][12];
char s[N];
struct SAM{
int Next[27],fa,Max;
}t[N<<1];
void extend(int c,int id){
int p=last,np=++size,q,nq;
tot[np][id]++;
t[np].Max=t[p].Max+1;
for (;!t[p].Next[c];p=t[p].fa)
t[p].Next[c]=np;
q=t[p].Next[c];
if (t[q].Max==t[p].Max+1)
t[np].fa=q;
else {
nq=++size;
t[nq]=t[q],t[nq].Max=t[p].Max+1;
t[q].fa=t[np].fa=nq;
for (;t[p].Next[c]==q;p=t[p].fa)
t[p].Next[c]=nq;
}
last=np;
}
int main(){
t[0].Max=-1;
for (int i=0;i<27;i++)
t[0].Next[i]=1;
scanf("%s",s);
m=strlen(s);
for (int i=0;i<m;i++)
extend(s[i]-'a',0);
scanf("%d",&n);
for (int i=1;i<=n;i++){
extend(26,n+1);
scanf("%s%d%d",s,&L[i],&R[i]);
m=strlen(s);
for (int j=0;j<m;j++)
extend(s[j]-'a',i);
}
for (int i=1;i<=size;i++)
tax[t[i].Max]++;
for (int i=1;i<=size;i++)
tax[i]+=tax[i-1];
for (int i=1;i<=size;i++)
id[tax[t[i].Max]--]=i;
LL ans=0;
for (int i=size;i>=2;i--){
int x=id[i];
for (int j=0;j<=n;j++)
tot[t[x].fa][j]+=tot[x][j];
if (tot[x][0]==0)
continue;
bool flag=1;
for (int j=1;flag&&j<=n;j++)
flag&=L[j]<=tot[x][j]&&tot[x][j]<=R[j];
if (flag)
ans+=t[x].Max-t[t[x].fa].Max;
}
printf("%I64d",ans);
return 0;
}

  

Codeforces 316G3 Good Substrings 字符串 SAM的更多相关文章

  1. Codeforces 1276F - Asterisk Substrings(SAM+线段树合并+虚树)

    Codeforces 题面传送门 & 洛谷题面传送门 SAM hot tea %%%%%%% 首先我们显然可以将所有能够得到的字符串分成六类:\(\varnothing,\text{*},s, ...

  2. Codeforces 235C Cyclical Quest 字符串 SAM KMP

    原文链接https://www.cnblogs.com/zhouzhendong/p/CF235C.html 题目传送门 -  CF235C 题意 给定一个字符串 $s$ ,多组询问,每组询问的形式为 ...

  3. Codeforces 452E Three strings 字符串 SAM

    原文链接https://www.cnblogs.com/zhouzhendong/p/CF542E.html 题目传送门 - CF452E 题意 给定三个字符串 $s1,s2,s3$ ,对于所有 $L ...

  4. Codeforces 873F Forbidden Indices 字符串 SAM/(SA+单调栈)

    原文链接https://www.cnblogs.com/zhouzhendong/p/9256033.html 题目传送门 - CF873F 题意 给定长度为 $n$ 的字符串 $s$,以及给定这个字 ...

  5. Codeforces 700E. Cool Slogans 字符串,SAM,线段树合并,动态规划

    原文链接https://www.cnblogs.com/zhouzhendong/p/CF700E.html 题解 首先建个SAM. 一个结论:对于parent树上任意一个点x,以及它所代表的子树内任 ...

  6. Codeforces Round #294 (Div. 2)D - A and B and Interesting Substrings 字符串

    D. A and B and Interesting Substrings time limit per test 2 seconds memory limit per test 256 megaby ...

  7. codeforces #271D Good Substrings

    原题链接:http://codeforces.com/problemset/problem/271/D 题目原文: D. Good Substrings time limit per test 2 s ...

  8. 【Codeforces 1037H】Security(SAM & 线段树合并)

    Description 给出一个字符串 \(S\). 给出 \(Q\) 个操作,给出 \(L, R, T\),求字典序最小的 \(S_1\),使得 \(S^\prime\) 为\(S[L..R]\) ...

  9. Codeforces 176B (线性DP+字符串)

    题目链接: http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=28214 题目大意:源串有如下变形:每次将串切为两半,位置颠倒形成 ...

随机推荐

  1. Confluence 6 配置服务器基础地址

    服务器基础地址(Server Base URL)是用户访问 Confluence 的 URL 地址.这个基础的 URL 地址必须与你在浏览器中访问 Confluence 中的地址. Confluenc ...

  2. Confluence 6 SQL Server 创建一个数据库和数据库用户

    一旦你成功安装了 SQL Server 服务器,请按照下面的方法为你的 Confluence 创建数据库用户和数据库: 使用你的 SQL 管理员权限,创建一个新的数据库(例如 confluence). ...

  3. Confluence 6 发送 Confluence 通知到其他 Confluence 服务器

    你可以配置 Confluence 服务器向其他的 Confluence 服务器发送消息.在这种情况下,Confluence 服务器将不会显示 workbox. 希望发送消息到其他 Confluence ...

  4. Django项目的创建及基本使用

    安装步骤 Django是Python进行Web开发的框架,目前应用比较广泛.使用python进行Web开发,能够很快的搭建所需的项目,可以运用于原型开发,也可以部署到实际的应用环境. 使用Django ...

  5. 开源框架 ImageLoader +ListView+GridView+RecyclerView 浅解

    下载地址 链接:https://pan.baidu.com/s/1ebz99pcuvHg2bODgeOtSbg 提取码:ia39 一.导入jar包或者添加依赖 jar包地址 导入jar包:将下载的ja ...

  6. python网络爬虫笔记(一)

    一.查询数据字典型数据 1.先说说dictionary查找和插入的速度极快,不会随着key的增加减慢速度,但是占用的内存大 2.list查找和插入的时间随着元素的增加而增加,但还是占用的空间小,内存浪 ...

  7. 基于Manhattan最小生成树的莫队算法

    点u,v的Manhattan距离:distance(u,v)= |x2-x1|+|y2-y1| Manhattan最小生成树:边权值为两个点Manhattan距离的最小生成树. 普通算法:prim复杂 ...

  8. CF451E

    一道不错的题,对排列组合能力的要求较高 题意:给定s个相同的小球放在n个不同的盒子里,可以不放,每个盒子有一个放的上限,求一共有多少种放法 解析:首先考虑没有上限的情况,这里比较好解决,采用隔板法,可 ...

  9. selenium 操作复选框

    场景 从上一节的例子中可以看出,webdriver可以很方便的使用findElement方法来定位某个特定的对象,不过有时候我们却需要定位一组对象, 这时候就需要使用findElements方法. 定 ...

  10. python 内置数据类型之字符串

    1.3 字符串 字符串本身就是一个有序(从左至右)的字符的集合.是序列这种类型的一种,后面还要学习列表与元组. 在这一节中,需要了解字符串的定义,特殊字符,转义与抑制转义:字符串基本操作.格式化等. ...