《算法竞赛进阶指南》1.6Trie
142. 前缀统计
给定N个字符串S1,S2…SN,接下来进行M次询问,每次询问给定一个字符串T,求S1~SN中有多少个字符串是T的前缀。
输入字符串的总长度不超过106,仅包含小写字母。
输入格式
第一行输入两个整数N,M。
接下来N行每行输入一个字符串Si。
接下来M行每行一个字符串T用以询问。
输出格式
对于每个询问,输出一个整数表示答案。
每个答案占一行。
输入样例:
3 2
ab
bc
abc
abc
efg
输出样例:
2
0
#include <iostream>
using namespace std;
const int N = 1000010, M = 500000; //trie 的长度
int n, m;
int son[M][26], cnt[N], idx; //cnt记录该节点是多少个字符串的末尾节点 idx 虚拟内存的指针(当前用到的数组的地址,当前节点的下标)
char str[N];
int query() //查询 字符串前缀个数
{
int p = 0, res = 0; //res 表示当前路径所有单词的总和
for(int i = 0; str[i]; i++)
{
int &s = son[p][str[i] - 'a'];
if(!s) break; //当前节点为空 没有下面的路径 break
p = s;
res += cnt[p]; //加上以当前节点为结尾的个数
}
return res;
}
void insert() //插入
{
int p = 0; //trie根节点 0号节点
for(int i = 0; str[i]; i++)
{
int &s = son[p][str[i] - 'a']; //当前儿子
if(!s) s = ++ idx; //s 不存在 分配一个新的值
p = s;
}
cnt[p] ++; //有一个单词以p节点为结尾 加1
}
int main()
{
scanf("%d%d", &n, &m); //输入规模大于100万用scanf()
while(n --)
{
scanf("%s", str);
insert();
}
while(m --)
{
scanf("%s", str);
printf("%d\n", query());
}
return 0;
}
143. 最大异或对
在给定的N个整数A1,A2……AN中选出两个进行xor(异或)运算,得到的结果最大是多少?
输入格式
第一行输入一个整数N。
第二行输入N个整数A1~AN。
输出格式
输出一个整数表示答案。
数据范围
1≤N≤105,
0≤Ai<231
输入样例:
3
1 2 3
输出样例:
3
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 100010, M = 3000000; //M节点个数
int n;
int son[M][2],idx;
int a[N];
void insert(int x)
{
int p = 0;
for(int i = 30; ~i; i--) //i >= 0 等价于 ~i
{
int &s = son[p][x >> i & 1]; //取出二进制第i位 看第i位是0还是1
if(!s) s = ++ idx; //创建新节点
p = s;
}
}
int query(int x)
{
int res = 0, p = 0;
for(int i = 30; ~i; i--)
{
int s = x >> i & 1;
if(son[p][!s]) //查看不一样的分支是否存在 1看0 0看1
{
res += 1 << i; //当前位对res所做出的贡献
p = son[p][!s];
}
else p = son[p][s];
}
return res;
}
int main()
{
cin >> n;
for(int i = 0; i < n; i++)
{
cin >> a[i];
insert(a[i]);
}
int res = 0;
for(int i = 0; i < n; i++) res = max(res, query(a[i])); //query 找到和当前异或最大的结果
cout << res << endl;
return 0;
}
144. 最长异或值路径
给定一个树,树上的边都具有权值。
树中一条路径的异或长度被定义为路径上所有边的权值的异或和:

⊕ 为异或符号。
给定上述的具有n个节点的树,你能找到异或长度最大的路径吗?
输入格式
第一行包含整数n,表示树的节点数目。
接下来n-1行,每行包括三个整数u,v,w,表示节点u和节点v之间有一条边权重为w。
输出格式
输出一个整数,表示异或长度最大的路径的最大异或和。
数据范围
1≤n≤100000,
0≤u,v<n,
0≤w<231
输入样例:
4
0 1 3
1 2 4
1 3 6
输出样例:
7
样例解释
样例中最长异或值路径应为0->1->2,值为7 (=3 ⊕ 4)
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int N = 100010, M = 3000000; //M节点个数
int n;
int h[N], e[N * 2], c[N * 2], ne[N * 2], cnt; //树:数组模拟邻接表来存,e无向图,边数*2,c是边权,ne存next指针,cnt内存,当前位下标
int son[M][2],idx;
int a[N];
void add(int u, int v, int w) //把u,v加到图里面去
{
e[cnt] = v, c[cnt] = w, ne[cnt] = h[u], h[u] = cnt ++; //数组模拟邻接表
}
void dfs(int u, int father, int sum)
{
a[u] =sum;
for(int i = h[u]; ~i; i = ne[i]) //遍历u这一点的所有儿子
{
int j = e[i]; //j表示儿子
if( j != father) //这条边的出边不是往上走的
dfs(j, u, sum ^ c[i]);
}
}
void insert(int x)
{
int p = 0;
for(int i = 30; ~i; i--) //i >= 0 等价于 ~i
{
int &s = son[p][x >> i & 1]; //取出二进制第i位 看第i位是0还是1
if(!s) s = ++ idx; //创建新节点
p = s;
}
}
int query(int x)
{
int res = 0, p = 0;
for(int i = 30; ~i; i--)
{
int s = x >> i & 1;
if(son[p][!s]) //查看不一样的分支是否存在 1看0 0看1
{
res += 1 << i; //当前位对res所做出的贡献
p = son[p][!s];
}
else p = son[p][s];
}
return res;
}
int main()
{
cin >> n;
memset(h, -1, sizeof h); //初始化邻接表表头
for(int i = 0; i < n - 1; i++)
{
int u, v, w;
cin >> u >> v >> w;
add(u, v, w);
add(v, u, w); //无向图 加两条边
}
dfs(0, -1, 0); //从根节点0开始,-1 无向图遍历常用方式 出边等于父节点 不回溯 ,sum 开始为 0
for(int i = 0; i < n; i++) insert(a[i]); //根节点到i的路径所有边权的xor值
int res = 0;
for(int i = 0; i < n; i++) res = max(res, query(a[i])); //query 找到和当前异或最大的结果
cout << res << endl;
return 0;
}
《算法竞赛进阶指南》1.6Trie的更多相关文章
- 《算法竞赛进阶指南》0x10 基本数据结构 Hash
Hash的基本知识 字符串hash算法将字符串看成p进制数字,再将结果mod q例如:abcabcdefg 将字母转换位数字(1231234567)=(1*p9+2*p8+3*p7+1*p6+2*p5 ...
- 《算法竞赛进阶指南》1.4Hash
137. 雪花雪花雪花 有N片雪花,每片雪花由六个角组成,每个角都有长度. 第i片雪花六个角的长度从某个角开始顺时针依次记为ai,1,ai,2,-,ai,6. 因为雪花的形状是封闭的环形,所以从任何一 ...
- bzoj 1787 && bzoj 1832: [Ahoi2008]Meet 紧急集合(倍增LCA)算法竞赛进阶指南
题目描述 原题连接 Y岛风景美丽宜人,气候温和,物产丰富. Y岛上有N个城市(编号\(1,2,-,N\)),有\(N-1\)条城市间的道路连接着它们. 每一条道路都连接某两个城市. 幸运的是,小可可通 ...
- POJ1639 算法竞赛进阶指南 野餐规划
题目描述 原题链接 一群小丑演员,以其出色的柔术表演,可以无限量的钻进同一辆汽车中,而闻名世界. 现在他们想要去公园玩耍,但是他们的经费非常紧缺. 他们将乘车前往公园,为了减少花费,他们决定选择一种合 ...
- 算法竞赛进阶指南 0x00 基本算法
放在原来这个地方不太方便,影响阅读体验.为了读者能更好的刷题,另起一篇随笔. 0x00 基本算法 0x01 位运算 [题目][64位整数乘法] 知识点:快速幂思想的灵活运用 [题目][最短Hamilt ...
- 算法竞赛进阶指南--快速幂,求a^b mod p
// 快速幂,求a^b mod p int power(int a, int b, int p) { int ans = 1; for (; b; b >>= 1) { if (b &am ...
- 算法竞赛进阶指南0x14 Hash
组成部分: 哈希函数: 链表 AcWing137. 雪花雪花雪花 因为所需要数据量过于大,所以只能以O(n)的复杂度. 所以不可能在实现的过程中一一顺时针逆时针进行比较,所以采用一种合适的数据结构. ...
- 《算法竞赛进阶指南》 1 (P4) a^b 快速幂
快速幂 #include<cstdio> #include<cmath> #include<iostream> using namespace std; long ...
- POJ1722 算法竞赛进阶指南 SUBSTRACT减操作
原题连接 题目描述 给定一个整数数组\(a_1,a_2,-,a_n\). 定义数组第 i 位上的减操作:把\(a_i\)和\(a_{i+1}\)换成\(a_i - a_{i+1}\). 用con(a, ...
随机推荐
- SQL server 数据库测试题
- HDU 3305 Ice-sugar Gourd
Ice-sugar Gourd Time Limit: 5000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)T ...
- mysql使用“.frm”文件恢复表结构
mysql创建每张表后都会在“mysql安装目录/data/数据库名/”目录下创建一个“表名.frm”文件. 该.frm文件并不能直接打开,但是它可以帮助你恢复你的表结构~~ 具体操作如下: 我现在准 ...
- iptables apache2
Apache2 iptables 安装指令:sudo apt-get install apache2 2.产生的启动和停止文件是:/etc/init.d/apache2 3.启动:sudo apach ...
- 【直播预告】7月25日3D游戏引擎免费公开课答疑第三期,有奖问答!
喜讯喜讯! 为了酬谢广大学员.CSDN学院特推出iOS和3D游戏引擎开发免费技术答疑公开课.让您度过一个充实的暑假~ 參与本次公开课,进行有奖问答.即有机会获奖. 答疑公开课时间:7月25日 晚7:3 ...
- Java的编程逻辑--15章 并发基础
1.run()和start()的区别 2.线程的基本属性和方法 id:一个递增的整数,每创建一个线程就加一 name 优先级:从1到10,默认为5,会映射到系统中的优先级.数字越大,要优先级越高 状态 ...
- TypeError: 'module' object is not callable 原因分析
程序代码 class Person: #constructor def __init__(self,name,sex): self.Name = name self.Sex = sex def ToS ...
- Spring中的事务管理(学习笔记)
什么是事物? 事物是指逻辑上的一组操作,这组操作要么全部成功,要么全部失败. 事物的特性: 原子性.一致性.隔离性.持久性 Spring事务管理的高级接口: PlatformTransactionMa ...
- mini_magick
https://github.com/minimagick/minimagick class https://www.rubydoc.info/github/minimagick/minimagic ...
- 浏览器和服务器 对post get请求 url长度限制
1. URL长度限制 2. Post数据的长度限制 3. Cookie的长度限制 1. GET URL长度限制 在Http1.1协议中并没有提出针对URL的长度进行限制,RFC协议里面是这样描述的, ...