2023年ICPC亚洲合肥赛区赛 C. Cyclic Substrings

题目

题解

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
// #define int long long
#define ll long long
const int maxn = 6e6 + 5;
const int mod = 998244353;
int fail[maxn];//fail[i]表示i结点代表的回文串的最大回文后缀的编号 
int len[maxn]; //len[i]表示结点i代表的回文串的长度 
int trie[maxn][26], tot = 1;//tot初始为1!!!! 
int cnt[maxn];//结点i代表的回文串出现了多少次
int ind[maxn];
string s;
int get(int x, int i){//x是以s[i-1]结尾的回文串,返回以s[i-1]结尾且s[i-len[x]-1]==s[i]的回文串的对应结点编号 
	while(i - len[x] - 1 < 0 || s[i - len[x] - 1] != s[i]) x = fail[x];
	return x;
}
signed main(){
	int i, j;
	int n;
	cin >> n;
	cin >> s;
	s = s + s;
	int cur = 0;
	int pos, last = 0;
	fail[0] = 1;
	fail[1] = 0;
	len[0] = 0;
	len[1] = -1;
	for(i = 0; i < 2 * n; i++){
		pos = get(cur, i);//cur是以s[i-1]结尾的最大回文串 
		int idx = s[i] - '0';
		if(!trie[pos][idx]){ 
			tot++; 
			int t = get(fail[pos], i);
			fail[tot] = trie[t][idx];
			ind[trie[t][idx]]++;
			trie[pos][idx] = tot;//把新建的结点接在pos下面 
			len[tot] = len[pos] + 2;
			// cnt[tot] = cnt[fail[tot]] + 1;
		}
		cur = trie[pos][idx];
		if(i > n - 1)//只计算以 后半串的字符 结尾的最长回文串,否则会重复
			cnt[cur]++;//结点cur代表的回文串出现了多少次
	}
	
	ll res = 0;
	queue<int> q;
	for(int i = 2; i <= tot; i++){
		// if(len[i] > n) continue;
		if(!ind[i]){
			q.push(i);
		}
	}
	while(!q.empty()){
		int u = q.front();
		q.pop();
		int v = fail[u];
		// if(len[v] > n) continue;
		cnt[v] += cnt[u];//一个回文串出现一次,那么它的回文后缀也出现一次
		if(--ind[v] == 0){
			q.push(v);
		}
	}
	for(int i = 2; i <= tot; i++){
		if(len[i] > n) continue;
		// cout << i << ' ' << len[i] << ' ' << cnt[i] << '\n';
		res = (res + 1LL * len[i] * cnt[i] % mod * cnt[i] % mod) % mod;
	}
	cout << res << '\n';
	return 0;
}
相关推荐
折哥的程序人生 · 物流技术专研6 小时前
Java面试85题图解版 · 特别篇:2026后端高频面试题复盘(算法底层逻辑+高并发架构设计全解析,附Java实战代码)
java·网络·数据库·算法·面试
想吃火锅10057 小时前
【leetcode】14.最长公共前缀js
算法·leetcode·职场和发展
云絮.8 小时前
数据库操作
数据库·mysql·算法·oracle
小林ixn8 小时前
LeetCode 206. 反转链表(迭代 + 递归详解)
算法·leetcode·链表
凡人叶枫9 小时前
Effective C++ 条款17:以独立语句将 newed 对象置入智能指针
java·linux·开发语言·c++·算法
菜鸟‍10 小时前
LeetCode 1 27 和 704 || 两数之和 移除元素 二分查找
算法·leetcode·职场和发展
退休倒计时11 小时前
【每日一题】LeetCode 142. 环形链表 II TypeScript
算法·leetcode·链表·typescript
popcorn_min12 小时前
Digits 手写数字识别:随机森林多分类 + 像素级特征热力图
算法·随机森林·分类
liulilittle12 小时前
拥塞控制:排水终止的两种决策:OR 与 AND
网络·tcp/ip·计算机网络·算法·信息与通信·tcp·通信
花间相见12 小时前
【LeetCode02】—— 两数之和:哈希表入门经典详解
数据结构·散列表