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 后缀自动机 并查集的更多相关文章

  1. BZOJ 4566 JZYZOJ 1547 [haoi2016T5]找相同子串 后缀数组 并查集

    http://172.20.6.3/Problem_Show.asp?id=1547 http://www.lydsy.com/JudgeOnline/problem.php?id=4566 单纯后缀 ...

  2. hdu 5458 Stability(树链剖分+并查集)

    Stability Time Limit: 3000/2000 MS (Java/Others)    Memory Limit: 65535/102400 K (Java/Others)Total ...

  3. NOI 2015 品酒大会 (后缀数组+并查集)

    题目大意:略 40分暴力还是很好写的,差分再跑个后缀和 和 后缀最大值就行了 一种正解是后缀数组+并查集 但据说还有后缀数组+单调栈的高端操作蒟蒻的我当然不会 后缀数组求出height,然后从大到小排 ...

  4. [HDU 3712] Fiolki (带边权并查集+启发式合并)

    [HDU 3712] Fiolki (带边权并查集+启发式合并) 题面 化学家吉丽想要配置一种神奇的药水来拯救世界. 吉丽有n种不同的液体物质,和n个药瓶(均从1到n编号).初始时,第i个瓶内装着g[ ...

  5. 51 nod 1456 小K的技术(强连通 + 并查集)

    1456 小K的技术 题目来源: CodeForces 基准时间限制:1 秒 空间限制:131072 KB 分值: 80 难度:5级算法题   苏塞克王国是世界上创新技术的领先国家,在王国中有n个城市 ...

  6. HDU 4622 Reincarnation(后缀自动机)

    [题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=4622 [题目大意] 给出一个长度不超过2000的字符串,有不超过10000个询问,问[L,R]子串 ...

  7. HDU 4436 str2int(后缀自动机)(2012 Asia Tianjin Regional Contest)

    Problem Description In this problem, you are given several strings that contain only digits from '0' ...

  8. 【hihocoder#1413】Rikka with String 后缀自动机 + 差分

    搞了一上午+接近一下午这个题,然后被屠了个稀烂,默默仰慕一晚上学会SAM的以及半天4道SAM的hxy大爷. 题目链接:http://hihocoder.com/problemset/problem/1 ...

  9. 牛客多校第四场 I string 后缀自动机/回文自动机

    这个回文自动机的板有问题,它虽然能过这道题,但是在计算size的时候会出锅! 题意: 求一个字符串中本质不同的连续子串有几个,但是某串和它反转后的字符串算一个. 题解: 要注意的是,一般字符串题中的“ ...

随机推荐

  1. 【前端】直击源头的让你3秒理解并且会用Jsonp!!!

    1. 同源策略 ajax之所以需要“跨域”,罪魁祸首就是浏览器的同源策略.即,一个页面的ajax只能获取这个页面相同源或者相同域的数据. 如何叫“同源”或者“同域”呢?——协议.域名.端口号都必须相同 ...

  2. IIS8.0 配置应用程序初始化功能

    IIS进程回收后,第一次访问会超级慢,这对于用户是不能接受的,怎么解决这个问题? 我们不能设置IIS不回收进程,因为这样可能会导致IIS内存泄漏.有效的方法时,尽量在业务空闲时间回收进程,回收后立刻预 ...

  3. UNIX环境高级编程 第8章 进程控制

    本章是UNIX系统中进程控制原语,包括进程创建.执行新程序.进程终止,另外还会对进程的属性加以说明,包括进程ID.实际/有效用户ID. 进程标识 每个进程某一时刻在系统中都是独一无二的,它们之间是用一 ...

  4. Red Hat Enterprise Linux 7.2下使用RPM包安装SQL Server vNext

    1.下载安装包 mssql-server:https://packages.microsoft.com/rhel/7/mssql-server/ mssql-tools:https://package ...

  5. PCI学习之总线原理01

    -----------以下资料由网络资料整理而成-------- PCI即Peripheral Component Interconnect,中文的意思是“外围器件互联”. PCI总线支持32位和64 ...

  6. 分布式git

    分布式 Git 你现在拥有了一个远程 Git 版本库,能为所有开发者共享代码提供服务,在一个本地工作流程下,你也已经熟悉 了基本 Git 命令.你现在可以学习如何利用 Git 提供的一些分布式工作流程 ...

  7. python网络编程-optparse

    Python 有两个内建的模块用于处理命令行参数: 一个是 getopt,<Deep in python>一书中也有提到,只能简单处理 命令行参数: 另一个是 optparse,它功能强大 ...

  8. Python_oldboy_自动化运维之路_全栈考试(五)

    1.执行 Python 脚本的两种方式 [root@localhost tmp]# cat a.py #!/usr/bin/python # -*- coding: UTF-8 -*- print & ...

  9. Oracle 中count(1) 、count(*) 和count(列名) 函数的区别

    1)count(1)与count(*)比较: 1.如果你的数据表没有主键,那么count(1)比count(*)快2.如果有主键的话,那主键(联合主键)作为count的条件也比count(*)要快3. ...

  10. GitHub如何使用

    先马克一下,有空看看:http://blog.csdn.net/xiahouzuoxin/article/details/9393119