hiho#1457 重复旋律7 求子串和 后缀自动机
题意:
给出若干个串,求所有子串的和,子串和的定义为十进制数,取模1e9+7.
思路:
对于一个串来说,一个状态p就代表着$right$相同的集合,假设我们已经知道了状态p的$sum$,以及状态p的$size$,假设p的下一位有一个c,p+c的状态为q,那么$sum[q]+=sum[p]*10+c*size[p]$,并且要更新$size[q]$,注意这里是“+=”,因为q也有可能通过其他方式得到。
而这道题的终点就是如何转移,显然是用拓扑,但困扰了我好久的就是如何处理一开始每个点的入度。
这是我一开始的代码。
for(int i=;i<=tot;i++){
for(int j=;j<;j++){
in[ch[i][j]]++;
}
}
这个代码的意思就是我把每个点和后面能抵达的点全部建边了,但这样答案会少,原因是有些点的入度永远不会0,所以少计算了,这个入度处理方式是错误的。
为什么呢?因为我们在处理多个串的时候,需要用一个':'符号来连接两个字符串,而这个符号刚好比‘9’大1,而我们下面用拓扑进行dp的时候,由于我们根本不会在队列里放入":"这个字符,所以形如$:5$这样的入度永远不会被减去,就无法入队。
所以我们处理入度的方式还是要用拓扑。
#include<bits/stdc++.h>
#define clr(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
const ll mod=1e9+;
const int maxn=;
char s[maxn];
int len[maxn<<],ch[maxn<<][],fa[maxn<<],tot=,root=,last=,siz,r[maxn<<];
int a[maxn<<],c[maxn<<],ans[maxn<<];
ll dp[maxn<<];
void extend(int x){
int now=++tot,pre=last;
last=now,len[now]=len[pre]+;
while( pre && !ch[pre][x]){
ch[pre][x]=now;
pre=fa[pre];
}
if(!pre)fa[now]=root;
else{
int q = ch[pre][x];
if(len[q]==len[pre]+)fa[now]=q;
else {
int nows=++tot;
memcpy(ch[nows],ch[q],sizeof(ch[q]));
len[nows]=len[pre]+;
fa[nows]=fa[q];
fa[q]=fa[now]=nows;
while(pre&&ch[pre][x]==q){
ch[pre][x]=nows;
pre=fa[pre];
}
}
}
}
bool vis[maxn<<];
int in[maxn<<];
int main(){
int n;
cin>>n;
while(n--){
scanf("%s",s);
siz=strlen(s);
for(int i=;i<siz;i++)
{
int p=s[i]-'';
extend(p);
}
extend();
}
queue<int >q;
q.push(); vis[] = ;
while(!q.empty()){
int x = q.front(); q.pop();
for(int c = ; c < ; c++){
int y = ch[x][c];
if(y == ) continue;
if(!vis[y])
q.push(y); vis[y] = ;
in[y]++;
}
}
q.push();
r[]=;
while(!q.empty()){
int i=q.front();
q.pop();
for(int j=;j<;j++){
int p=ch[i][j];
if(p){
r[p]=(r[p]+r[i])%mod;
dp[p]=(dp[p]+dp[i]*%mod+j*r[i]%mod)%mod;
if(--in[p]==){
q.push(p);
}
}
}
} ll res=;
for(int i=;i<=tot;i++){
res=(res+dp[i])%mod;
}
cout<<res<<endl; }
hiho#1457 重复旋律7 求子串和 后缀自动机的更多相关文章
- hiho#1445 重复旋律5 求子串数量 后缀自动机
题目传送门 题意:给出一个字符串,求子串的个数. 思路:后缀自动机的题真是每做一题就更理解一些. SAM中的每一状态$p$都代表了一种子串,而p包含的字符串的个数是$len[p]-len[fa[p]] ...
- hiho# 1465 重复旋律8 循环串计数 后缀自动机
题目传送门 题意:给出一个母串,再给出n个串,问对于每个串,母串中有几个子串是可以通过循环变化得到这个串. 思路:对母串建SAM,求出$right$集. 把匹配串复制一遍,和母串进行匹配,当匹配长度大 ...
- hiho#1449 重复旋律6 求长度为k的串最大次数 后缀自动机
题目传送门 题目大意:求长度为k的串的最大次数,把k从1到length的所有答案全部输出. 思路: 这道题放在$SAM$里就是求长度$k$对应的所有$right$集中最大的大小. 我们以$aabab$ ...
- 【BZOJ4032】[HEOI2015]最短不公共子串(后缀自动机,序列自动机)
[BZOJ4032][HEOI2015]最短不公共子串(后缀自动机,序列自动机) 题面 BZOJ 洛谷 题解 数据范围很小,直接暴力构建后缀自动机和序列自动机,然后直接在两个自动机上进行\(bfs\) ...
- hihocoder 1457 后缀自动机四·重复旋律7 求不同子串的和
描述 小Hi平时的一大兴趣爱好就是演奏钢琴.我们知道一段音乐旋律可以被表示为一段数构成的数列. 神奇的是小Hi发现了一部名字叫<十进制进行曲大全>的作品集,顾名思义,这部作品集里有许多作品 ...
- hihocoder 后缀自动机五·重复旋律8 求循环同构串出现的次数
描述 小Hi平时的一大兴趣爱好就是演奏钢琴.我们知道一段音乐旋律可以被表示为一段数构成的数列. 小Hi发现旋律可以循环,每次把一段旋律里面最前面一个音换到最后面就成为了原旋律的“循环相似旋律”,还可以 ...
- SPOJ1811最长公共子串问题(后缀自动机)
题目:http://www.spoj.com/problems/LCS/ 题意:给两个串A和B,求这两个串的最长公共子串. 分析:其实本题用后缀数组的DC3已经能很好的解决,这里我们来说说利用后缀自动 ...
- CODE【VS】3160 最长公共子串 (后缀自动机)
3160 最长公共子串 题目描述 Description 给出两个由小写字母组成的字符串,求它们的最长公共子串的长度. 输入描述 Input Description 读入两个字符串 输出描述 Outp ...
- bzoj千题计划318:bzoj1396: 识别子串(后缀自动机 + 线段树)
https://www.lydsy.com/JudgeOnline/problem.php?id=1396 后缀自动机的parent树上,如果不是叶子节点,那么至少有两个子节点 而一个状态所代表子串的 ...
随机推荐
- [Training Video - 2] [Java Introduction] [Install Java and Eclipse, Create Class]
Download Java : https://java.com/en/download/ Download Eclipse : https://www.eclipse.org/downloads/ ...
- spark yarn 集群提交kafka代码
配置好hadoop的环境,具体根据http://blog.csdn.net/u010638969/article/details/51283216博客所写的进行配置. 运行start-dfs.sh启动 ...
- C++友元函数、友元类
1.什么是友元函数? 友元函数就是可以直接访问类的成员(包括私有数据)的非成员函数,也就是说他并不属于这个类,他是一种外部的函数. 一个外部函数只能通过类的授权成为这个类友元函数,这就涉及到一个关键字 ...
- centos 虚拟机中修改屏幕分辨率
1.$ vi /boot/grub/grub.conf(路径可能会不一样,也可以是 /etc/grub.conf),打开grub.conf文件 2.我们修改分辨率,需要在kernel那行加入 vga= ...
- [转]解决Mysql InnoDB: Failing assertion: ret || !assert_on_error问题
国庆回来后,发现mysql停止服务了,没办法继续启动了.查看日志,看到: 131008 09:56:03 mysqld_safe Starting mysqld daemon with databas ...
- GBK还是UTF-8? Eclipse连接TFS的编码之痛!encoding, encoding, encoding…
在中文Windows操作系统上安装Eclipse或MyEclipse,默认会将Eclipse的编码设置为GBK,与操作系统的默认编码保存一致. 在这种默认设置下,在Eclipse新增的文件不会自动被团 ...
- Linux TCP不同状态的连接数统计
方法一:利用netstat命令 统计 TIME_WAIT/CLOSE_WAIT/ESTABLISHED/LISTEN 等TCP状态的连接数 netstat -tan |grep ^tcp |awk ' ...
- 新手上路,django学习笔记(1) 环境部署
很多年没写代码了,以前学的C#,用ASP.NET,但是最近几年没落了,JAVA在崛起,最近感觉Python比较火,总是在各种技术场合听到Python,或者身边的朋友在讨论Python,所以突然想学习一 ...
- osgi.net框架
osgi.net是一个动态的模块化框架.它向用户提供了模块化与插件化.面向服务构架和模块扩展支持等功能.该平台是OSGi联盟定义的服务平台规范移植到.NET的实现. 简介 尤埃开放服务平台是一个基于. ...
- TypeScript白鹭引擎Egret防止按钮事件冒泡穿透
this.addEventListener(egret.TouchEvent.TOUCH_BEGIN, (event) => { if (event.target!=this) return;/ ...