随笔 - 216,  文章 - 0,  评论 - 17,  阅读 - 25574

节点 u 对应的:
子串数量为 len(u)len(link(u))
所有后缀的长度为 len(u)(len(u)+1)2

时间复杂度:建立自动机 O(n)

https://www.luogu.com.cn/problem/P3804

给定字符串 s,求出 s 的所有出现次数不为 1 的子串的出现次数乘上该子串长度的最大值。

#include<bits/stdc++.h>
using namespace std;
using LL = long long;
struct SAM{
	static constexpr int N = 1e6;
	struct node{
		int len, link, nxt[26];
		int siz;
	}t[N << 1];
	int cntNodes;
	SAM(){
		cntNodes = 1;
		fill(t[0].nxt, t[0].nxt + 26, 1);
		t[0].len = -1;
	}
	int extend(int p, int c){
		if (t[p].nxt[c]){
			int q = t[p].nxt[c];
			if (t[q].len == t[p].len + 1){
				return q;
			}
			int r = ++ cntNodes;
			t[r].siz = 0;
			t[r].len = t[p].len + 1;
			t[r].link = t[q].link;
			copy(t[q].nxt, t[q].nxt + 26, t[r].nxt);
			t[q].link = r;
			while (t[p].nxt[c] == q){
				t[p].nxt[c] = r;
				p = t[p].link;
			}
			return r;
		}
		int cur = ++ cntNodes;
		t[cur].len = t[p].len + 1;
		t[cur].siz = 1;
		while (!t[p].nxt[c]){
			t[p].nxt[c] = cur;
			p = t[p].link;
		}
		t[cur].link = extend(p, c);
		return cur;
	}
};
int main(){
	ios::sync_with_stdio(false);cin.tie(0);
	string s;
	cin >> s;
	
	SAM sam;
	int p = 1;
	for (auto c : s){
		p = sam.extend(p, c - 'a');
	}
	
	vector<vector<int>> G(sam.cntNodes + 1);
	for (int i = 2; i <= sam.cntNodes; i ++ ){
		G[sam.t[i].link].push_back(i);
	}
	LL ans = 0;
	function<void(int)> dfs = [&](int u){
		for (auto v : G[u]){
			dfs(v);
			sam.t[u].siz += sam.t[v].siz;
		}
		if (sam.t[u].siz > 1){
			ans = max(ans, 1LL * sam.t[u].siz * sam.t[u].len);
		}
	};
	dfs(1);
	cout << ans << "\n";
	return 0;
}

https://codeforc.es/problemset/problem/1780/G
找出出现次数可以被串长度整除的串的数量
https://codeforc.es/problemset/problem/616/F
计算出现次数长度权重最大

posted on   Hamine  阅读(196)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

点击右上角即可分享
微信分享提示