传送门

调代码调的我怀疑人生。

启发式合并用迭代写怎么都跑不过(雾

换成了dfsdfsdfs版本的终于过了233.

题意简述:求给出nnn个字串,对于每个给定的字串求出其有多少个字串在至少kkk个剩下字串中出现过。


显然先对所有字串建一个samsamsam出来,然后对于每个状态用一个setsetset维护在哪些字串里面出现过(这个显然需要在建完parentparentparent树之后启发式合并一波),最后拿每个串在上面匹配,如果当前的状态不满足题意就沿着树边向上跳即可。

代码:

#include<bits/stdc++.h>
#define ri register int
using namespace std;
const int M=2e5+5;
int k,T;
string s[M];
typedef long long ll;
struct SAM{
	int last,tot,len[M],son[M][26],link[M],cnt[M],rk[M],val[M];
	set<int>S[M];
	vector<int>e[M];
	SAM(){last=tot=1,len[0]=-1,fill(son[0],son[0]+26,1);}
	inline void expand(int x,int id){
		int p=last,np=++tot;
		S[last=np].insert(id),len[np]=len[p]+1;
		while(p&&!son[p][x])son[p][x]=np,p=link[p];
		if(!p){link[np]=1;return;}
		int q=son[p][x],nq;
		if(len[q]==len[p]+1){link[np]=q;return;}
		len[nq=++tot]=len[p]+1,memcpy(son[nq],son[q],sizeof(son[q])),link[nq]=link[q];
		while(p&&son[p][x]==q)son[p][x]=nq,p=link[p];
		link[q]=link[np]=nq;
	}
	inline void merge(int u,int v){
		if(S[u].empty()||S[v].empty())return;
		for(set<int>::iterator it=S[v].begin();it!=S[v].end();++it)S[u].insert(*it);
	}
	inline void dfs(int p){
		for(ri i=0,v;i<e[p].size();++i){
			dfs(v=e[p][i]);
			if(S[p].size()<S[v].size())swap(S[p],S[v]);
			for(set<int>::iterator it=S[v].begin();it!=S[v].end();++it)S[p].insert(*it);
		}
		val[p]=S[p].size();
	}
	inline void solve(){
		for(ri i=1;i<=tot;++i)if(link[i])e[link[i]].push_back(i);
		dfs(1);
	}
	inline ll query(int id){
		int p=1,up=s[id].size(),nowlen=0;
		ll ret=0;
		for(ri i=0;i<up;++i){
			p=son[p][s[id][i]-'a'];
			while(val[p]<k)p=link[p];
			ret+=len[p];
		}
		return ret;
	}
}sam;
int main(){
	scanf("%d%d",&T,&k);
	for(ri i=1,n;i<=T;++i){
		cin>>s[i];
		n=s[i].size();
		for(ri j=0;j<n;++j)sam.expand(s[i][j]-'a',i);
		sam.last=1;
	}
	if(k>T){for(ri i=1;i<=T;++i)cout<<"0 ";return 0;}
	sam.solve();
	for(ri i=1;i<=T;++i)cout<<sam.query(i)<<' ';
	return 0;
}

2018.12.22 bzoj3473: 字符串(后缀自动机+启发式合并)的更多相关文章

  1. loj#6041. 「雅礼集训 2017 Day7」事情的相似度(后缀自动机+启发式合并)

    题面 传送门 题解 为什么成天有人想搞些大新闻 这里写的是\(yyb\)巨巨说的启发式合并的做法(虽然\(LCT\)的做法不知道比它快到哪里去了--) 建出\(SAM\),那么两个前缀的最长公共后缀就 ...

  2. 2018.12.22 bzoj3277: 串(后缀自动机+启发式合并)

    传送门 跟这道题是一模一样的. 于是本蒟蒻又写了一遍10min1A庆祝 代码: #include<bits/stdc++.h> #define ri register int using ...

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

    模板—字符串—后缀自动机(后缀自动机+线段树合并求right集合) Code: #include <bits/stdc++.h> using namespace std; #define ...

  4. [TJOI2019]甲苯先生和大中锋的字符串——后缀自动机+差分

    题目链接: [TJOI2019]甲苯先生和大中锋的字符串 对原串建后缀自动机并维护$parent$树上每个点的子树大小,显然子树大小为$k$的节点所代表的子串出现过$k$次,那么我们需要将$[len[ ...

  5. LOJ#6503.「雅礼集训 2018 Day4」Magic[容斥+NTT+启发式合并]

    题意 \(n\) 张卡牌 \(m\) 种颜色,询问有多少种本质不同的序列满足相邻颜色相同的位置数量等于 \(k\). 分析 首先本质不同不好直接处理,可以将同种颜色的卡牌看作是不相同的,求出答案后除以 ...

  6. 2018.12.22 spoj7258 Lexicographical Substring Search(后缀自动机)

    传送门 samsamsam基础题. 题意简述:给出一个串,询问第kkk大的本质不同的串. 然而这就是弦论的简化版. 我们把samsamsam建出来然后贪心选择就行了. 代码: #include< ...

  7. 2018.12.22 bzoj3926: [Zjoi2015]诸神眷顾的幻想乡(广义后缀自动机)

    传送门 题意简述:给出一棵trietrietrie树,每个点表示一个字符,求树上所有路径组成的不同字串数.(叶子数≤20\le 20≤20) 由于有一个神奇的条件,考虑以每一个叶子为树根统计每个点到树 ...

  8. BZOJ3473:字符串(后缀数组,主席树,二分,ST表)

    Description 给定n个字符串,询问每个字符串有多少子串(不包括空串)是所有n个字符串中至少k个字符串的子串? Input 第一行两个整数n,k. 接下来n行每行一个字符串. Output 一 ...

  9. Wannafly Camp 2020 Day 2D 卡拉巴什的字符串 - 后缀自动机

    动态维护任意两个后缀的lcp集合的mex,支持在串末尾追加字符. Solution 考虑在 SAM 上求两个后缀的 LCP 的过程,无非就是找它们在 fail 树上的 LCA,那么 LCP 长度就是这 ...

随机推荐

  1. c# 关闭和重启.exe程序

    Process[] myprocess = Process.GetProcessesByName("a"); if (myprocess.Count() > 0)//判断如果 ...

  2. MYSQL中替换oracle中runum用法

    一 . SELECT * FROM (SELECT A.*, rownum AS RN FROM (SELECT (@rownum := @rownum + 1) AS rownum, B.LL11, ...

  3. maven 打 fat包(jar包有了全部依赖)插件

    <plugin> <artifactId> maven-assembly-plugin </artifactId> <configuration> &l ...

  4. classLoader.getResourceAsStream中文乱码

    一直用一个方法安然无恙,今天在新项目中突然乱码了,原代码: ClassLoader classLoader = Thread.currentThread().getContextClassLoader ...

  5. swift - self的弱引用

    1. weak var weakSelf = self 2. DispatchQueue.main.asyncAfter(deadline: DispatchTime.now()) {[weak se ...

  6. Python爬虫项目--爬取自如网房源信息

    本次爬取自如网房源信息所用到的知识点: 1. requests get请求 2. lxml解析html 3. Xpath 4. MongoDB存储 正文 1.分析目标站点 1. url: http:/ ...

  7. bootstrap 折叠collapse失效

    手动点击折叠,然后调用折叠全部以后,在手动点击折叠项,折叠失效. 方法,折叠项是通过添加或删除".in"来实现,实现如下 $(".collapse.in").c ...

  8. JFinal Web开发学习(九)后台添加前台显示博客

    效果: 发博客: 显示博客: 后台:使用hui-admin,文章编辑器是百度开源的ueditor 前台:使用layui前端框架 1.写控制器BlogController controller包中 pa ...

  9. Oracle_PL/SQL(10) 定时器job

    定时器job1.定义 定时器指在特定的时间执行特定的操作. 可以多次执行.说明:特定的操作:指一个完成特定功能的存储过程.多次执行:指可以每分钟.每小时.每天.每周.每月.每季度.每年等周期性的运行. ...

  10. Liunx ls命令

    ls命令是linux下最常用的命令.ls命令就是list的缩写缺省下ls用来打印出当前目录的清单如果ls指定其他目录那么就会显示指定目录里的文件及文件夹清单. 通过ls 命令不仅可以查看linu ...