玄关求调90分RE第二个点
  • 板块P1481 魔族密码
  • 楼主wwy123
  • 当前回复1
  • 已保存回复1
  • 发布时间2025/2/8 16:11
  • 上次更新2025/2/8 18:01:10
查看原帖
玄关求调90分RE第二个点
1303781
wwy123楼主2025/2/8 16:11
#include <bits/stdc++.h>
typedef unsigned int u32;
struct Trie{
	/*
	 * 每个节点有两个信息:
	 * pass:有多少个字符串经过这个结点
	 * end:有多少个字符串以这个结点结尾
	 * 头节点的pass值:一共添加过多少个字符串(一共有多少个字符串以空字符串开头)
	 * 				  任意一个节点的pass值可以反应有多少个字符串以这个字串开头
	 * 前缀性质:若出现某一个结点的pass = 0则与这个结点相连的后续所有结点的pass都
	 * 将为0所以全部删除
	 */
	struct Node{
		u32 end = 0;
		u32 pass = 0;
		Node* next[50] = {nullptr};
	};
	Node *root = nullptr;
	char base;
	Trie(bool tag = true){
		root = new Node;
		//root->end = root->pass = 0;
		base = (base ? 'a' : 'A');
	}
	void insert(std::string s){
		Node* t = root;
		t->pass++;
		for (u32 i = 0, path;i < s.length();++i){
			path = (u32)(s.at(i) - base);
			if(t->next[path] == nullptr){
				t->next[path] = new Node;
			}
			t = t->next[path];
			t->pass++;
		}
		t->end++;
	}
	// 统计s一共出现了几次
	int query(std::string s){
		Node* t = root;
		for (u32 i = 0, path;i < s.length();++i){
			path = (u32)(s[i] - base);
			if(t->next[path] == nullptr){
				return 0;
			}
			t = t->next[path];
		} 
		return t->end;
	}
	void erase(std::string s){
		if(query(s) > 0){
			Node* t = root;
			t->pass--;
			for (u32 i = 0, path;i < s.length();++i){
				path = s.at(i) - base;
				if(--t->next[path]->pass == 0){
					t->next[path] = nullptr;
					return;
				}
				t = t->next[path];
			}
			t->end--;
		}
	}
	// 统计 s 拥有的前缀子串数量不算空串
	int query_pre(std::string s){
		Node* t = root;
		int ans = 0;
		for (u32 i = 0, path;i < s.length(); ++i){
			path = (u32)(s.at(i) - base);
			if(t->next[path] == nullptr){
				return ans;
			}
			ans += t->end;
			t = t->next[path];
		}
		ans += t->end;
		return ans;
	}
	// 统计有多少个单词以s为前缀
	int query_pre1(std::string s){
		Node* t = root;
		for (u32 i = 0, path;i < s.length();++i){
			path = (u32)(s.at(i) - base);
			if(t->next[path] == nullptr){
				return 0;
			}
			t = t->next[path];
		}
		return t->pass;
	}
	Node* getroot(){return root;}
	int dfs(Node* t){
	 	int temp = 0;
	 	//int a = 0; 
		for (u32 i = 0;i < 26;++i){
			if(t->next[i] != nullptr){
				temp = std::max(dfs(t->next[i]) + t->next[i]->end, temp + t->next[i]->end);
			}
		}
		return temp;
	}
};

//struct Trie tree(true);

// temp 记录结点所有分支中的end的和的最大

int main(){
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);
	std::cout.tie(nullptr);
	int n;
	struct Trie tree(true);
	std::cin >> n;
	if(n == 0){
		std::cout << 0;
		return 0;
	}
	std::string s[2005];
	int i = 0;
	while(n--){
		std::cin >> s[i];
		tree.insert(s[i]);
		i++;
	}
	int ans = 0;
	while(i--){
		ans = std::max(ans, tree.query_pre(s[i]));
	}
	std::cout << ans << '\n';
}

这是记录https://www.luogu.com.cn/record/202010498

2025/2/8 16:11
加载中...