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

acwing: https://www.acwing.com/problem/content/837/

在集合中插入字符串,询问字符串在集合中出现了多少次。

#include <bits/stdc++.h>
using namespace std;
#define LL long long
const int N = 1e5 + 10;
LL q;
string s;
struct Trie{
	LL ch[N][26], cnt[N], idx = 0;
	void insert(string s){
		LL u = 0;
		for (int i = 0; i < s.size(); i ++ ){
			LL v = s[i] - 'a';
			if (!ch[u][v]) ch[u][v] = ++ idx;
			u = ch[u][v];
		}
		cnt[u] ++ ;
	}
	LL query(string s){
		LL u = 0;
		for (int i = 0; i < s.size(); i ++ ){
			LL v = s[i] - 'a';
			if (!ch[u][v]) return 0;
			u = ch[u][v];
		}
		return cnt[u];
	}
}trie;
int main(){
	ios::sync_with_stdio(false);cin.tie(0);
	cin >> q;
	for (int i = 1; i <= q; i ++ ){
		char op;
		cin >> op >> s;
		if (op == 'I'){
			trie.insert(s);
		}
		else{
			cout << trie.query(s) << "\n";
		}
	}
	return 0;
}

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

给定 n 个模式串 s1,s2,...,snq 次询问,每次询问给定一个文本串 ti,问它是多少个模式串的前缀

#include <bits/stdc++.h>
using namespace std;
#define LL int
const int N = 3e6 + 10;
LL T, n, q;
string s;
struct Trie{
	LL ch[N][63], cnt[N], idx = 0;
	map <char, LL> mp;
	void init(){
		LL id = 0;
		for (char c = 'a'; c <= 'z'; c ++ )
			mp[c] = ++ id;
		for (char c = 'A'; c <= 'Z'; c ++ )
			mp[c] = ++ id;
		for (char c = '0'; c <= '9'; c ++ )
			mp[c] = ++ id;
	}
	void insert(string s){
		LL u = 0;
		for (int i = 0; i < s.size(); i ++ ){
			LL v = mp[s[i]];
			if (!ch[u][v]) ch[u][v] = ++ idx;
			u = ch[u][v];
			cnt[u] ++ ;
		}
	}
	LL query(string s){
		LL u = 0;
		for (int i = 0; i < s.size(); i ++ ){
			LL v = mp[s[i]];
			if (!ch[u][v]) return 0;
			u = ch[u][v];
		}
		return cnt[u];
	}
	void Clear(){
		for (int i = 0; i <= idx; i ++ ){
			cnt[i] = 0;
			for (int j = 0; j <= 62; j ++ ){
				ch[i][j] = 0;
			}
		}
		idx = 0;
	}
}trie;
void solve(){
	cin >> n >> q;
	for (int i = 1; i <= n; i ++ ){
		cin >> s;
		trie.insert(s);
	}
	for (int i = 1; i <= q; i ++ ){
		cin >> s;
		cout << trie.query(s) << "\n";
	}
	trie.Clear();
}
int main(){
	ios::sync_with_stdio(false);cin.tie(0);
	trie.init();
	cin >> T;
	while (T -- )
		solve();
	return 0;
}

01 trie

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

给定一棵树,求最大异或路径和。

思路:

先通过 dfs 求出每个点到根节点的异或和,最大的一段路径和就是在所有点到根节点的路径和中找到异或和最大的那两个
这题卡空间,需将 ch 改为数组才能过,vector 会超限。

#include <bits/stdc++.h>
using namespace std;
using LL = long long;
struct Trie{
	int n, idx = 0;
	vector<vector<int>> ch;
	Trie(int n) : n(n), ch(n * 30, vector<int>(2)) {}
	void insert(int x){
		int u = 0;
		for (int i = 30; ~ i; i -- ){
			int &v = ch[u][x >> i & 1];
			if (!v) v = ++ idx;
			u = v;
		}
	}
	int query(int x){
		int u = 0, res = 0;
		for (int i = 30; ~ i; i -- ){
			int v = x >> i & 1;
			if (ch[u][!v]){
				res += (1 << i);
				u = ch[u][!v];
			}
			else{
				u = ch[u][v];
			}
		}
		return res;
	}
};
const int N = 1e5 + 10;
vector<pair<int, int>> e[N];
int a[N];
void dfs(int u, int p){
	for (auto [v, w] : e[u]){
		if (v == p){
			continue;
		}
		a[v] = a[u] ^ w;
		dfs(v, u);
	}
}
int main(){
	ios::sync_with_stdio(false);cin.tie(0);
	int n;
	cin >> n;
	for (int i = 1; i < n; i ++ ){
		int u, v, w;
		cin >> u >> v >> w;
		e[u].push_back({v, w});
		e[v].push_back({u, w});
	}
	dfs(1, 0);
	Trie trie(n);
	for (int i = 1; i <= n; i ++ ){
		trie.insert(a[i]);
	}
	int ans = 0;
	for (int i = 1; i <= n; i ++ ){
		ans = max(ans, trie.query(a[i]));
	}
	cout << ans << "\n";
	return 0;
}
posted on   Hamine  阅读(68)  评论(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

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