蓝书2.3 Trie字典树
T1 IMMEDIATE DECODABILITY poj 1056
题目大意:
一些数字串 求是否存在一个串是另一个串的前缀
思路:
对于所有串经过的点权+1 如果一个点的end被访问过或经过一个被标记为end的点 就存在
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
#include<set>
#define inf 2139062143
#define ll long long
#define MAXN 15100
using namespace std;
inline int read()
{
int x=,f=;char ch=getchar();
while(!isdigit(ch)) {if(ch=='-') f=-;ch=getchar();}
while(isdigit(ch)) {x=x*+ch-'';ch=getchar();}
return x*f;
}
int n,tr[][],T,ans,vis[MAXN],sz,end[MAXN];
char ch[];
void ins(char *c,int len)
{
int pos=;
for(int i=;i<len;i++)
{
if(!tr[pos][c[i]-'']) tr[pos][c[i]-'']=++sz;
pos=tr[pos][c[i]-''],vis[pos]++;
if(end[pos]) ans=;
}
if(vis[pos]>) ans=;end[pos]=;
}
int main()
{
while(scanf("%s",ch)!=EOF)
{
ans=sz=;memset(vis,,sizeof(vis));
memset(tr,,sizeof(tr));memset(end,,sizeof(end));
while(ch[]!=''){ins(ch,strlen(ch));scanf("%s",ch);}
if(!ans) printf("Set %d is immediately decodable\n",++T);
else printf("Set %d is not immediately decodable\n",++T);
}
}
T2 L语言 bzoj 1212
题目大意:
给字典 求一个字符串能被字典解释的最长前缀
思路:
因为字典内的单词都很短
可以对每一个模式串的位置向后匹配递推
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
#include<set>
#define inf 2139062143
#define ll long long
#define MAXN 1000100
using namespace std;
inline int read()
{
int x=,f=;char ch=getchar();
while(!isdigit(ch)) {if(ch=='-') f=-;ch=getchar();}
while(isdigit(ch)) {x=x*+ch-'';ch=getchar();}
return x*f;
}
int n,m,tr[][],sz,end[MAXN],f[MAXN];
char ch[],s[MAXN];
void ins(char *c,int len)
{
int pos=;
for(int i=;i<len;i++)
{
if(!tr[pos][c[i]-'a']) tr[pos][c[i]-'a']=++sz;
pos=tr[pos][c[i]-'a'];
}
end[pos]=;
}
int query(char *c,int len)
{
int pos=,res=,k;
if(tr[pos][c[]-'a']) f[]=;
else return ;
for(int i=;i<len;i++)
{
if(!f[i]) continue;
pos=tr[pos][c[i]-'a'],k=;
while(pos)
{
if(end[pos]) f[i+k+]=,res=max(res,min(i+k+,len));
pos=tr[pos][c[i+k+]-'a'],k++;
}
}
return res;
}
int main()
{
n=read(),m=read();
for(int i=;i<=n;i++) {scanf("%s",ch);ins(ch,strlen(ch));}
while(m--)
{
scanf("%s",s);memset(f,,sizeof(f));
printf("%d\n",query(s,strlen(s)));
}
}
T3 秘密信息 bzoj 1590
题目大意:
思路:
加到字典序里记一下经过的end标记和这个密码的end位置有多少个信息经过
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
#include<set>
#define inf 2139062143
#define ll long long
#define MAXN 500100
using namespace std;
inline int read()
{
int x=,f=;char ch=getchar();
while(!isdigit(ch)) {if(ch=='-') f=-;ch=getchar();}
while(isdigit(ch)) {x=x*+ch-'';ch=getchar();}
return x*f;
}
int n,m,tr[MAXN][],sz,end[MAXN],s[MAXN];
void ins(int len)
{
int pos=;
for(int i=,k;i<len;i++)
{
k=read();
if(!tr[pos][k]) tr[pos][k]=++sz;
pos=tr[pos][k],s[pos]++;
}
end[pos]++;
}
int query(int len)
{
int pos=,res=,f=;
for(int i=,k;i<len;i++)
{
k=read();
if(f) continue;pos=tr[pos][k];
if(!pos) f=;
if(i!=len-) res+=end[pos];
}
if(!f) res+=s[pos];
return res;
}
int main()
{
n=read(),m=read();int k;
for(int i=;i<=n;i++) {k=read();ins(k);}
while(m--) {k=read();printf("%d\n",query(k));}
}
T4 背单词 bzoj 4567
题目大意:
放n个单词,放每个单词之前如果没有把这个单词的后缀都先放上去则代价为n*n)
每个单词的代价等于这个单词的位置减去上一个出现的这个单词的后缀的位置(若没有后缀则代价为它的位置)
求最少的代价
思路:
首先肯定要把所有单词的后缀都加入否则代价太大
然后倒着把单词加入建trie树 对于所有end节点向上最近的end连边
可以得到一个树 每个树按照size从小到大遍历
答案就是所有节点的序号-父亲的序号
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
#include<set>
#define inf 2139062143
#define ll long long
#define MAXN 500100
using namespace std;
inline int read()
{
int x=,f=;char ch=getchar();
while(!isdigit(ch)) {if(ch=='-') f=-;ch=getchar();}
while(isdigit(ch)) {x=x*+ch-'';ch=getchar();}
return x*f;
}
int n,m,tr[MAXN][],tot,end[MAXN],st[MAXN],top;
ll ans;
char ch[MAXN],s[MAXN];
int fst[MAXN],nxt[MAXN],to[MAXN],cnt,fa[MAXN],sz[MAXN];
void add(int u,int v) {nxt[++cnt]=fst[u],fst[u]=cnt,to[cnt]=v;}
void ins(char *c,int len)
{
int pos=,tmp=;
for(int i=len-;i>=;i--)
{
if(!tr[pos][c[i]-'a']) tr[pos][c[i]-'a']=++tot;
pos=tr[pos][c[i]-'a'];
}
end[pos]=;
}
void dfs(int x,int anc)
{
if(end[x]) {add(x,anc);add(anc,x);fa[x]=anc,anc=x;}
for(int i=;i<;i++)
if(tr[x][i]) dfs(tr[x][i],anc);
}
void build(int x)
{
sz[x]=;
for(int i=fst[x];i;i=nxt[i])
if(to[i]!=fa[x]) {build(to[i]);sz[x]+=sz[to[i]];}
}
bool cmp(int x,int y) {return sz[x]<sz[y];}
void dfs(int x)
{
int l=top+,r;ll s=;
for(int i=fst[x];i;i=nxt[i]) if(to[i]!=fa[x])st[++top]=to[i];
sort(st+l,st+top+,cmp);r=top;
for(int i=l;i<=r;i++) {ans+=s,s+=sz[st[i]];dfs(st[i]);}
}
int main()
{
n=read();
for(int i=;i<=n;i++) {scanf("%s",ch);ins(ch,strlen(ch));}
dfs(,);build();dfs();printf("%lld\n",ans);
}
T5 The xor-longest Path bzoj 1954
题解链接 唯一的区别是poj 从0开始
蓝书2.3 Trie字典树的更多相关文章
- 萌新笔记——C++里创建 Trie字典树(中文词典)(一)(插入、遍历)
萌新做词典第一篇,做得不好,还请指正,谢谢大佬! 写了一个词典,用到了Trie字典树. 写这个词典的目的,一个是为了压缩一些数据,另一个是为了尝试搜索提示,就像在谷歌搜索的时候,打出某个关键字,会提示 ...
- Trie字典树 动态内存
Trie字典树 #include "stdio.h" #include "iostream" #include "malloc.h" #in ...
- 算法导论:Trie字典树
1. 概述 Trie树,又称字典树,单词查找树或者前缀树,是一种用于快速检索的多叉树结构,如英文字母的字典树是一个26叉树,数字的字典树是一个10叉树. Trie一词来自retrieve,发音为/tr ...
- 标准Trie字典树学习二:Java实现方式之一
特别声明: 博文主要是学习过程中的知识整理,以便之后的查阅回顾.部分内容来源于网络(如有摘录未标注请指出).内容如有差错,也欢迎指正! 系列文章: 1. 标准Trie字典树学习一:原理解析 2.标准T ...
- 817E. Choosing The Commander trie字典树
LINK 题意:现有3种操作 加入一个值,删除一个值,询问pi^x<k的个数 思路:很像以前lightoj上写过的01异或的字典树,用字典树维护数求异或值即可 /** @Date : 2017- ...
- C++里创建 Trie字典树(中文词典)(一)(插入、遍历)
萌新做词典第一篇,做得不好,还请指正,谢谢大佬! 写了一个词典,用到了Trie字典树. 写这个词典的目的,一个是为了压缩一些数据,另一个是为了尝试搜索提示,就像在谷歌搜索的时候,打出某个关键字,会提示 ...
- 数据结构 -- Trie字典树
简介 字典树:又称单词查找树,Trie树,是一种树形结构,是一种哈希树的变种. 优点:利用字符串的公共前缀来减少查询时间,最大限度地减少无谓的字符串比较,查询效率比哈希树高. 性质: 1. 根节 ...
- 踹树(Trie 字典树)
Trie 字典树 ~~ 比 KMP 简单多了,无脑子选手学不会KMP,不会结论题~~ 自己懒得造图了OI WIKI 真棒 字典树大概长这么个亚子 呕吼真棒 就是将读进去的字符串根据当前的字符是什么和所 ...
- Trie(字典树)解析及其在编程竞赛中的典型应用举例
摘要: 本文主要讲解了Trie的基本思想和原理,实现了几种常见的Trie构造方法,着重讲解Trie在编程竞赛中的一些典型应用. 什么是Trie? 如何构建一个Trie? Trie在编程竞赛中的典型应用 ...
随机推荐
- CentOS7安装Tomcat9并设置开机启动
1.下载 Tomcat 9 CentOS 7 下创建目录并下载文件: cd /usr/local/ mkdir tomcat cd tomcat wget http://mirrors.hust.ed ...
- c++基础_矩阵乘法
#include <iostream> using namespace std; int main(){ int a,b; cin>>a>>b; long c[a] ...
- HUAS Summer Contest#4 D题 DP
Description Speakless很早就想出国,现在他已经考完了所有需要的考试,准备了所有要准备的材料,于是,便需要去申请学校了.要申请国外的任何大学,你都要交纳一定的申请费用,这可是很惊人的 ...
- Spring 事物注解属性
@Transactional属性 . propagation 事物的传播属性 . isolation 事物的隔离属性 . readonly 设置只读属性 . timeout 设置超时属性 . roll ...
- 【05】AJAX实例-检测用户名是否存在(实例)
AJAX实例-检测用户名是否存在 用户注册时,需要填写个人信息,其中包括用户名.当用户输入完成时,JavaScript 需要及时检测用户名是否存在,如果存在给出提示,请用户更换用户名. 当然,这个 ...
- HTML基础知识 table中 th,td,tr
https://www.2cto.com/kf/201711/701872.html table是一个布局神器,之前看过很多代码,都是用table布局的.但是,我在学习的过程中,发现table有很迷的 ...
- linux & chmod & 777
linux & chmod & 777 https://github.com/xgqfrms-GitHub/Node-CLI-Tools/blob/master/bash-shell- ...
- [luoguP1021] 邮票面值设计(DFS + dp)
传送门 数据很小,可以DFS,判断的时候用背包DP 然而不知到枚举到哪里.... 首先枚举前可以求一遍题目中的MAX,下一层DFS的时候可以只枚举到MAX + 1,因为再往上就必定会出现断层 蒟蒻很菜 ...
- java 构造不可变类集的使用方法
首先用到的就是Collections.unmodifiablexxx( set.add("hello"); set.add("insert ...
- [K/3Cloud] 创建一个业务单据表单插件
概念 创建一个业务单据插件,处理单据的相关控制逻辑. 示例 新建一个类,继承自单据插件基类Kingdee.BOS.Core.Bill.PlugIn.AbstractBillPlugIn. using ...