NOIP前 基础字符串模板

/*
	created by scarlyw
	基础字符串模板 
*/
#include <bits/stdc++.h>

//kmp O(n)匹配
namespace knuth_morris_pratt {

//kmp字符串匹配,s为模式串,t为匹配串 
const int MAXN = 1000000 + 10;
char s[MAXN], t[MAXN];
int p[MAXN];
bool flag;
//获得next数组 
inline void get_next(char *s) {
	int len = strlen(s), j = -1;
	p[0] = -1;
	for (int i = 1; i < len; ++i) {
		while (j != -1 && s[j + 1] != s[i]) j = p[j];
		if (s[j + 1] == s[i]) ++j;
		p[i] = j;
	}
}

//输出为在匹配串中出现的位置, 匹配串下标为1开始 
inline void match(char *s, char *t) {
	int lens = strlen(s), lent = strlen(t), j = -1;
	for (int i = 0; i < lent; ++i) {
		while (j != -1 && s[j + 1] != t[i]) j = p[j];
		if (s[j + 1] == t[i]) ++j;
		if (j == lens - 1)
			std::cout << i - lens + 2 << '\n', j = p[j];
	} 
}
}

//manacher算法 
namespace palindrome_string {

//O(n) manacher,ans保存最长的回文串长度 
const int MAXN = 300000 + 10;
char s[MAXN], s1[MAXN];
int p[MAXN], len;
inline int manacher(char *s1) {
	s[0] = '!', s[1] = '#', len = strlen(s1 + 1);
	for (int i = 1; i <= len; ++i) s[i << 1] = s1[i], s[i << 1 | 1] = '#';
	s[len * 2 + 2] = '?';
	int n = len * 2 + 1, id = 0, mr = 0, ans = 0;
	for (int i = 1; i <= n; ++i) {
		if (mr > i) p[i] = std::min(p[2 * id - i], mr - i);
		else p[i] = 1;
		while (s[i - p[i]] == s[i + p[i]]) ++p[i];
		if (p[i] - 1 > ans) ans = p[i] - 1;
		if (i + p[i] > mr) mr = i + p[i], id = i;
	}
	return ans;
}
}

//trie字典树 
namespace trie_tree {

//trie树 
const int ALP = 10;
const int MAXN = 100000 + 1000;
int c, n, cnt;
char s[MAXN / 10][20];
struct trie {
	int son[ALP];
	bool end;
} t[MAXN];

//插入一个字符串 
inline void insert(char *s) {
	int len = strlen(s), pos = 0;
	for (int i = 0; i < len; ++i) {
		if (t[pos].son[s[i] - '0'] == 0) t[pos].son[s[i] - '0'] = ++cnt;
		pos = t[pos].son[s[i] - '0'];
	}
	t[pos].end = true;
}

//查询是否有串为当前串的前缀 
inline bool query(char *s) {
	int len = strlen(s), pos = 0;
	for (int i = 0; i < len; ++i) {
		if (t[pos].end) return false;
		pos = t[pos].son[s[i] - '0'];
	}
	return true;
}

//清空 
inline void clear() {
	for (int i = 0; i <= cnt; ++i) 
		memset(t[i].son, 0, sizeof(t[i].son)), t[i].end = false;
	cnt = 0;
}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值