初涉trie
trie:字符串算法中的重要“数据结构”
什么是trie
trie就是利用字符串的公共前缀所建成的树。
众所周知树是有很多很好的性质的,于是trie可以结合其他知识点做一些有趣的事情。
trie的例题
注意
trie的题一般数组开成$f[lensSum][size]$,其中$lensSum$是所有字符串的长度之和,$size$是字符集大小。
【判断前缀】poj3630Phone List
Description
Given a list of phone numbers, determine if it is consistent in the sense that no number is the prefix of another. Let's say the phone catalogue listed these numbers:
- Emergency 911
- Alice 97 625 999
- Bob 91 12 54 26
In this case, it's not possible to call Bob, because the central would direct your call to the emergency line as soon as you had dialled the first three digits of Bob's phone number. So this list would not be consistent.
Input
The first line of input gives a single integer, 1 ≤ t ≤ 40, the number of test cases. Each test case starts with n, the number of phone numbers, on a separate line, 1 ≤ n ≤ 10000. Then follows n lines with one unique phone number on each line. A phone number is a sequence of at most ten digits.
Output
For each test case, output "YES" if the list is consistent, or "NO" otherwise.
Sample Input
2
3
911
97625999
91125426
5
113
12340
123440
12345
98346
Sample Output
NO
YES
题目分析
这个是trie最基础的应用——判断前缀。
#include<cstdio>
#include<cctype>
#include<cstring>
const int maxn = ;
const int maxe = ; int tt,n,tot;
int f[maxn][maxe];
char ch[maxe];
bool vis[maxn],fl; int read()
{
char ch = getchar();
int num = ;
bool fl = ;
for (; !isdigit(ch); ch = getchar())
if (ch=='-') fl = ;
for (; isdigit(ch); ch = getchar())
num = (num<<)+(num<<)+ch-;
if (fl) num = -num;
return num;
}
void insert(char *s)
{
int n = strlen(s), rt = ;
for (int i=; i<n; i++)
{
int w = s[i]-'';
if (!f[rt][w]) f[rt][w] = ++tot;
else if (i==n-) fl = ;
rt = f[rt][w];
if (vis[rt]) fl = ;
}
vis[rt] = ;
}
int main()
{
tt = read();
while (tt--)
{
memset(vis, , sizeof vis);
memset(f, , sizeof f);
fl = , tot = , n = read();
for (int i=; i<=n; i++)
{
scanf("%s",ch);
insert(ch);
}
printf("%s\n",!fl?"YES":"NO");
}
return ;
}
【前缀统计】bzoj1590: [Usaco2008 Dec]Secret Message 秘密信息
Description
Input
Output
题目分析
#include<bits/stdc++.h>
const int maxn = ;
const int maxe = ;
const int maxNode = ; struct node
{
int end,pass;
}a[maxNode];
int f[maxNode][maxe];
int n,m,lens,tot,r[maxn]; int read()
{
char ch = getchar();
int num = ;
bool fl = ;
for (; !isdigit(ch); ch = getchar())
if (ch=='-') fl = ;
for (; isdigit(ch); ch = getchar())
num = (num<<)+(num<<)+ch-;
if (fl) num = -num;
return num;
}
void insert()
{
int u = ;
for (int i=; i<=lens; i++)
{
if (!f[u][r[i]]) f[u][r[i]] = ++tot;
u = f[u][r[i]];
a[u].pass++;
}
a[u].pass--, a[u].end++;
}
void query()
{
int cnt = , u = ;
for (int i=; i<=lens; i++)
{
u = f[u][r[i]];
if (!u) break;
cnt += a[u].end;
}
cnt += a[u].pass;
printf("%d\n",cnt);
}
int main()
{
tot = , n = read(), m = read();
for (int i=; i<=n; i++)
{
lens = read();
for (int j=; j<=lens; j++) r[j] = read();
insert();
}
for (int i=; i<=m; i++)
{
lens = read();
for (int j=; j<=lens; j++) r[j] = read();
query();
}
return ;
}
【xor最值】bzoj4260: Codechef REBXOR
Description
Input
Output
Sample Input
1 2 3 1 2
Sample Output
HINT
题目分析
这题就是要稍加建模的题了。
若用dp的思想:$l[i]$表示$1≤l≤r≤i$的最大异或和,$r[i]$表示$i≤l≤r≤n$的最大异或和,那么有$ans=max\{l[i]+r[i+1]\}$。
问题就在于求$l[i],r[i]$,这里讨论$l[i]$的求法,$r[i]$同理。若$r!=i$,那么$l[i]=l[i-1]$;否则就是固定了右端点,再找一个左端点使得$a[x]~a[i]$异或和最大。
粗看xor是没有前缀和加法性质的。但是这不就等于在一个集合里找一个数求其与给定数最大的异或和吗?这就转化成为trie的另一个经典应用了。
#include<bits/stdc++.h>
const int maxn = ;
const int maxe = ; int n,tot,cnt,ans;
int f[maxn<<][maxe],a[maxn];
int l[maxn],r[maxn]; int read()
{
char ch = getchar();
int num = ;
bool fl = ;
for (; !isdigit(ch); ch = getchar())
if (ch=='-') fl = ;
for (; isdigit(ch); ch = getchar())
num = (num<<)+(num<<)+ch-;
if (fl) num = -num;
return num;
}
void insert(int x)
{
int u = ;
for (int i=<<; i; i>>=)
{
int c = (x&i)?:;
if (!f[u][c]) f[u][c] = ++tot;
u = f[u][c];
}
}
int find(int x)
{
int u = , ret = ;
for (int i=<<; i; i>>=)
{
int c = (x&i)?:;
if (f[u][c])
ret += i, u = f[u][c];
else u = f[u][-c]; //这里u打成c调了半小时……
}
return ret;
}
int main()
{
n = read();
for (int i=; i<=n; i++) a[i] = read();
memset(f, , sizeof f);
tot = , cnt = , insert();
for (int i=; i<=n; i++)
{
cnt ^= a[i];
insert(cnt);
l[i] = std::max(l[i-], find(cnt));
}
memset(f, , sizeof f);
tot = , cnt = , insert();
for (int i=n; i>=; i--)
{
cnt ^= a[i];
insert(cnt);
r[i] = std::max(r[i+], find(cnt));
}
for (int i=; i<n; i++)
ans = std::max(ans, l[i]+r[i+]);
printf("%d\n",ans);
return ;
}
END
初涉trie的更多相关文章
- NOIP2018 - 暑期博客整理
暑假写的一些博客复习一遍.顺便再写一遍或者以现在的角度补充一点东西. 盛暑七月 初涉基环外向树dp&&bzoj1040: [ZJOI2008]骑士 比较经典的基环外向树dp.可以借鉴的 ...
- 基于trie树做一个ac自动机
基于trie树做一个ac自动机 #!/usr/bin/python # -*- coding: utf-8 -*- class Node: def __init__(self): self.value ...
- 基于trie树的具有联想功能的文本编辑器
之前的软件设计与开发实践课程中,自己构思的大作业题目.做的具有核心功能,但是还欠缺边边角角的小功能和持久化数据结构,先放出来,有机会一点点改.github:https://github.com/chu ...
- [LeetCode] Implement Trie (Prefix Tree) 实现字典树(前缀树)
Implement a trie with insert, search, and startsWith methods. Note:You may assume that all inputs ar ...
- hihocoder-1014 Trie树
hihocoder 1014 : Trie树 link: https://hihocoder.com/problemset/problem/1014 题意: 实现Trie树,实现对单词的快速统计. # ...
- 【BZOJ-2938】病毒 Trie图 + 拓扑排序
2938: [Poi2000]病毒 Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 609 Solved: 318[Submit][Status][Di ...
- Poj The xor-longest Path 经典题 Trie求n个数中任意两个异或最大值
Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 5646 Accepted: 1226 Description In an ...
- 二分+DP+Trie HDOJ 5715 XOR 游戏
题目链接 XOR 游戏 Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total ...
- 【hihoCoder】1036 Trie图
题目:http://hihocoder.com/problemset/problem/1036 给一个词典dict,词典中包含了一些单词words.要求判断给定的一个文本串text中是否包含这个字典中 ...
随机推荐
- IT兄弟连 JavaWeb教程 JSP中的三大指令
指令标识主要用于设定整个JSP页面范围内都有效的相关信息,它是被服务器解释并执行的,不会产生任何内容输出到网页中.也就是说,指令标识对于客户端浏览器是不接见的.JSP页面的指令标识与我们的身份证类似, ...
- Java - 安装jdk并设置环境变量
前言 双十一买了台新的笔记本,需要重新安装下Java,这里记录下安装的过程,毕竟万事开头难,就算是老手也不一定能一次就把Java安装成功. 安装jdk 作为一名Java开发,当然是要安装jdk了,如果 ...
- android BottomNavigationView 底部显示3个以上的item
你现在可以用app:labelVisibilityMode="[labeled, unlabeled, selected, auto] labeled 所有的标签都是可见的. unlabel ...
- FMDB存储模型对象(以二进制存储)用NSKeyedArchiver archivedDataWithRootObject序列号,NSKeyedUnarchiver unarchiveObjectWithData反序列化(重点坑是sql语句@"insert into t_newsWithChannel (nwesName,newsType) values (?,?)")一定要用占位符
交友:微信号 dwjluck2013 一.封装FMDB单例 (1)JLFMDBHelp.h文件 #import <Foundation/Foundation.h> #import < ...
- 【bzoj1718】Redundant Paths 分离的路径
1718: [Usaco2006 Jan] Redundant Paths 分离的路径 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 964 Solve ...
- springMVC-RESTful支持
RESTful支持 什么是restful? Restful就是一个资源定位及资源操作的风格.不是标准也不是协议,只是一种风格,是对http协议的诠释. 资源定位:互联网所有的事物都是资源,要求url中 ...
- python入门之冒泡排序
原理: (白话描述)一列数,从左到右,依次两两比较,若左边的数大于右边的数,则两数交换,始终保持比较后左边的数小于右边的数,这样从第一个到最后一个数全部比较一次就会把这列数中的最大值排到最后(最右边) ...
- php设计模式学习之工厂模式
我的认为:所为工厂模式是事先有一系类class,一个工厂类' 工厂类根据不同的参数创建不同的对象,调用各自的方法; php利用工厂模式实现计算器: ?php /** * Created by PhpS ...
- 解决Git在更新项目时报凭证错误(Authentication failed)
报此错误,大概率原因是用户名和密码弄错了,我用的阿里云,在网上找了半天发现Git远程仓库用的用户名和密码不是阿里云登陆用的账户密码,必须另外设置: 链接:code.aliyun.com/profile ...
- Ubuntu 16.04 not a com32r image
安装Ubuntu16.04,出现题目中的错误,解决方法如下 重点:开机后按TAB键,在随后出现的命令行提示符中输入live 既可,之后的过程就是正常的过程了!