BZOJ1174 - Toponyms(trie)
题意
给你一个字符集合,你从其中找出一些字符串出来. 希望你找出来的这些字符串的最长公共前缀*字符串的总个数最大化.
思路
先建好trie树,然后dfs预处理每个子树下单词个数,同时计算最大值即可。
但是因为数据很大,字符可能的种类很多,要用tr树要用邻接表实现。实测vector也不行。
点击展开代码
#include <bits/stdc++.h>
#define endl '\n'
#define IOS std::ios::sync_with_stdio(0); cin.tie(0); cout.tie(0)
#define FILE freopen(".//data_generator//in.txt","r",stdin),freopen("res.txt","w",stdout)
#define FI freopen(".//data_generator//in.txt","r",stdin)
#define FO freopen("res.txt","w",stdout)
#define pb push_back
#define mp make_pair
#define seteps(N) fixed << setprecision(N)
typedef long long ll;
using namespace std;
/*-----------------------------------------------------------------*/
ll gcd(ll a, ll b) {return b ? gcd(b, a % b) : a;}
#define INF 0x3f3f3f3f
const int N = 5e6 + 10;
const double eps = 1e-5;
struct node {
char p;
int nt, ne;
};
int head[N];
node tr[N];
bool flag[N];
string s;
int si;
int ct;
ll ans;
void insert(const char str[]) {
int cur = 0;
for(int i = 0; str[i]; i++) {
bool found = false;
char p = str[i];
for(int e = head[cur]; e; e = tr[e].ne) {
if(tr[e].p == p) {
cur = tr[e].nt;
found = true;
break;
}
}
if(!found) {
tr[++si] = node {p, ++ct, head[cur]};
head[cur] = si;
cur = ct;
}
}
flag[cur] = 1;
}
int dfs(int cur, int dep) {
int cnt = flag[cur];
for(int e = head[cur]; e; e = tr[e].ne) {
cnt += dfs(tr[e].nt, dep + 1);
}
ans = max(ans, 1ll * dep * cnt);
return cnt;
}
int main() {
//FI;
IOS;
int n;
cin >> n;
cin.ignore();
for(int i = 1; i <= n; i++) {
getline(cin, s);
insert(s.c_str());
}
dfs(0, 0);
cout << ans << endl;
}
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 解答了困扰我五年的技术问题
· 为什么说在企业级应用开发中,后端往往是效率杀手?
· 用 C# 插值字符串处理器写一个 sscanf
· Java 中堆内存和栈内存上的数据分布和特点
· 开发中对象命名的一点思考
· 为什么说在企业级应用开发中,后端往往是效率杀手?
· DeepSeek 解答了困扰我五年的技术问题。时代确实变了!
· 本地部署DeepSeek后,没有好看的交互界面怎么行!
· 趁着过年的时候手搓了一个低代码框架
· 推荐一个DeepSeek 大模型的免费 API 项目!兼容OpenAI接口!