HDU 1277
HDU 1277 全文检索
题意
给定一个很长的字符串,因为很长所以分成很多行,全为数字组成,不少于60个,不多于60000个。
然后给定一些需要检索的串,个数不超过10000个,每个串长度不超过60。问哪些串出现在文本串中。
思路
知道是字典树,但不知道怎么建树,也不知道从哪里入手,之后看题解才发现是让检索的串形成一棵树,然后从文本串的每一位开始遍历,然后每次遍历字典树最多只有O(60),总的时间复杂度为O(60*60000)
代码
#include <iostream>
#include <bits/stdc++.h>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <string>
#include <map>
#include <set>
#define int long long
#define endl "\n"
#define pii pair<int,int>
using namespace std;
typedef unsigned long long ull;
const int mod=1e9+7,N=2e6+10,M=1e4+10,inf=1e18;
int n,m;
int son[N][10],ed[N],idx,flag,len;
string str,s,tmp;
void insert(string s,int id)
{
int p=0;
for(int i=0;s[i];i++)
{
int c = s[i]-'0';
if(!son[p][c]) son[p][c]=++idx;
p=son[p][c];
}
ed[p]=id;
}
void fd(int be)
{
int p=0;
for(int i=be;str[i];i++)
{
int c=str[i]-'0';
if(ed[p])
{
if(flag==0)
{
cout<<"Found key:";
flag=1;
}
cout<<" [Key No. "<<ed[p]<<"]";
ed[p]=0;
}
if(!son[p][c]) return;
p=son[p][c];
}
}
void solve()
{
flag=0;
cin>>n>>m;
for(int i=1;i<=n;i++)
{
cin>>tmp;
str=str+tmp;
}
for(int i=1;i<=m;i++)
{
cin>>tmp>>tmp>>tmp>>s;
//因为读入是[Key No. 1] 数字串
//为了过滤掉前面的那些字符
insert(s,i);
}
for(int i=0;str[i];i++)
{
fd(i);
}
if(flag==0) cout<<"No key can be found !"<<endl;
else cout<<endl;
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t=1;
//cin>>t;
while(t--) solve();
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)