HDU 4641 K-string 后缀自动机 并查集
http://acm.hdu.edu.cn/showproblem.php?pid=4641
https://blog.csdn.net/asdfgh0308/article/details/40969047
给一个小写字母字符串,1 a表示在字符串尾部添加一个小写字母a,2 表示当前有多少种子串出现次数大于等于K。
求出现次数桶排序(说是拓扑排序也可以?)就阔以了,种类就是t[i].len-t[t[i].f].len。
在线处理是直接扫描,时间复杂度是O(树高*m)。
离线做法是先把所有添加操作都做完,然后去掉字母反向求子串种数,可以使用并查集降低时间复杂度(每个连通块中只有总父亲表示的子串对当前答案有贡献,保证了每个点的平均扫描次数)。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
using namespace std;
#define LL long long
const int maxn=;
int n,m,K;
char ch[maxn*],ch1[];
int e[maxn*]={},b[maxn*]={},siz;
struct nod{
int sig[],f,len;
}t[maxn*]; int tot,la; int cnt[maxn*]={},rk[maxn*]={};
int fa[maxn*]={},sub[maxn*]={},g[maxn*]={};
LL ans[maxn*]={}; void addit(int z){
int x=++tot,i=la; t[x].len=t[i].len+;
b[siz]=x;
for(;i&&!t[i].sig[z];i=t[i].f)t[i].sig[z]=x;
if(!i)t[x].f=;
else{
int y=t[i].sig[z];
if(t[y].len==t[i].len+)t[x].f=y;
else{
int p=++tot;
t[p]=t[y];t[p].len=t[i].len+;
t[y].f=t[x].f=p;
for(;i&&t[i].sig[z]==y;i=t[i].f)t[i].sig[z]=p;
}
}
la=x;
}
void msort(){
int i;
for(i=;i<=siz;i++)cnt[i]=;
for(i=;i<=tot;i++)cnt[t[i].len]++;
for(i=;i<=siz;i++)cnt[i]+=cnt[i-];
for(i=tot;i>;i--)rk[cnt[t[i].len]--]=i;
}
int getfa(int x){
int y=x,z;
while(y!=fa[y])y=fa[y];
while(x!=fa[x]){ z=x; x=fa[x];fa[z]=y;}
return fa[x];
}
int main(){
int i,p,y; LL num;
while(~scanf("%d%d%d",&n,&m,&K)){
memset(t,,sizeof(t)); tot=; la=; siz=;
scanf("%s",ch);
for(i=;i<n;++i){ addit(ch[i]-'a'); ++siz; }
for(i=;i<=m;i++){
scanf("%d",&e[i]);
if(e[i]==){ scanf("%s",ch1); addit(ch1[]-'a'); ch[siz++]=ch1[]; }
}
msort(); p=,num=;
for(i=;i<=tot;i++){ g[i]=; fa[i]=i; sub[i]=;}
for(i=;i<siz;++i){ p=t[p].sig[ch[i]-'a']; ++g[p]; }
for(i=tot-;i>;i--){ p=rk[i]; if(t[p].f!=)g[t[p].f]+=g[p]; }
for(i=;i<=tot;++i){ if(g[i]>=K) num+=t[i].len-t[t[i].f].len; }
for(i=m;i>;i--){
if(e[i]==)ans[i]=num;
else{
p=b[--siz];
y=getfa(p);
while(y!=&&g[y]<K){ fa[y]=getfa(t[y].f); y=fa[y];}
y=getfa(p);
if(y==)continue;
sub[y]++;
while(y!=&&(g[y]-sub[y]<K)){
num-=t[y].len-t[t[y].f].len;
p=getfa(t[y].f);
sub[p]+=sub[y]; fa[y]=p;
y=fa[y];
}
}
}
for(i=;i<=m;++i)if(e[i]==)printf("%lld\n",ans[i]);
}
return ;
}
HDU 4641 K-string 后缀自动机 并查集的更多相关文章
- BZOJ 4566 JZYZOJ 1547 [haoi2016T5]找相同子串 后缀数组 并查集
http://172.20.6.3/Problem_Show.asp?id=1547 http://www.lydsy.com/JudgeOnline/problem.php?id=4566 单纯后缀 ...
- hdu 5458 Stability(树链剖分+并查集)
Stability Time Limit: 3000/2000 MS (Java/Others) Memory Limit: 65535/102400 K (Java/Others)Total ...
- NOI 2015 品酒大会 (后缀数组+并查集)
题目大意:略 40分暴力还是很好写的,差分再跑个后缀和 和 后缀最大值就行了 一种正解是后缀数组+并查集 但据说还有后缀数组+单调栈的高端操作蒟蒻的我当然不会 后缀数组求出height,然后从大到小排 ...
- [HDU 3712] Fiolki (带边权并查集+启发式合并)
[HDU 3712] Fiolki (带边权并查集+启发式合并) 题面 化学家吉丽想要配置一种神奇的药水来拯救世界. 吉丽有n种不同的液体物质,和n个药瓶(均从1到n编号).初始时,第i个瓶内装着g[ ...
- 51 nod 1456 小K的技术(强连通 + 并查集)
1456 小K的技术 题目来源: CodeForces 基准时间限制:1 秒 空间限制:131072 KB 分值: 80 难度:5级算法题 苏塞克王国是世界上创新技术的领先国家,在王国中有n个城市 ...
- HDU 4622 Reincarnation(后缀自动机)
[题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=4622 [题目大意] 给出一个长度不超过2000的字符串,有不超过10000个询问,问[L,R]子串 ...
- HDU 4436 str2int(后缀自动机)(2012 Asia Tianjin Regional Contest)
Problem Description In this problem, you are given several strings that contain only digits from '0' ...
- 【hihocoder#1413】Rikka with String 后缀自动机 + 差分
搞了一上午+接近一下午这个题,然后被屠了个稀烂,默默仰慕一晚上学会SAM的以及半天4道SAM的hxy大爷. 题目链接:http://hihocoder.com/problemset/problem/1 ...
- 牛客多校第四场 I string 后缀自动机/回文自动机
这个回文自动机的板有问题,它虽然能过这道题,但是在计算size的时候会出锅! 题意: 求一个字符串中本质不同的连续子串有几个,但是某串和它反转后的字符串算一个. 题解: 要注意的是,一般字符串题中的“ ...
随机推荐
- D - Doing Homework HDU - 1074 (状压dp)
题目链接:https://cn.vjudge.net/contest/68966#problem/D 具体思路:我们可以把每个情况都枚举出来,然后用递归的形式求出最终的情况. 比如说 我们要求 10 ...
- CMD命令利用tasklist与taskkill关闭程序
昨天远程服务器后,服务器无故卡住了,鼠标各种延迟与无反应,想在进程管理器里关闭程序也卡住,想点击重启系统也卡死无反应.纠结后win+R打开了cmd用shutdown重启才算搞定.重启期间思考了下,如何 ...
- Struts2笔记1:--Struts2原理、优点、编程流程、6大配置文件以及核心配置文件struts.xml
Struts2原理(底层使用的是Servlet的doFilter方法): Struts2优点: 第一个Struts程序: 在开发Struts程序之前,首先要导入额外的jar包,基本需求的是14个jar ...
- Linux XOR.DDoS样本取证特征与清除
一.取证特征 1)获取进程ID 使用top命令,查看占用内存率最高的十位随机名称进程名(示例:进程名pygdykcrqf) 2)获取进程对应路径 Linux 在启动一个进程时,系统会在/proc下创建 ...
- connect系统调用
/* * Attempt to connect to a socket with the server address. The address * is in user space so we ve ...
- Genymotion上不能安装APK软件的问题
Genymotion模拟器不能安装APK的原因 官网给出的解释:Genymotion模拟器使用的是x86架构,在第三方市场上的应用有部分不采用x86这么一种架构,所以在编译的时候不通过,报“APP n ...
- vue总结 03过滤器
过滤器 Vue.js 允许你自定义过滤器,可被用于一些常见的文本格式化.过滤器可以用在两个地方:双花括号插值和 v-bind 表达式 (后者从 2.1.0+ 开始支持).过滤器应该被添加在 JavaS ...
- ubuntu12.04安装ruby2.3
为了搭建github-pages博客,而github-pages后端依赖于ruby,且对版本有严格要求,自己尝试了各种姿势升级ruby2.3无果,最终在查阅了各种资料之后找到一个可行方案. icebu ...
- mvn本地库导入jar包
导入脚本 #!/bin/sh mvn deploy:deploy-file -DgroupId=com.xxx.xxx -DartifactId=包名 -Dversion=4.0 -Dpackag ...
- hdu 5446(2015长春网络赛J题 Lucas定理+中国剩余定理)
题意:M=p1*p2*...pk:求C(n,m)%M,pi小于10^5,n,m,M都是小于10^18. pi为质数 M不一定是质数 所以只能用Lucas定理求k次 C(n,m)%Pi最后会得到一个同余 ...