Day10 堆排序、模拟堆 trie树(字典树) 并查集
堆呢就是一棵树完全二叉树。。。
小根堆的话,根节点就是最小值
维护堆只有两个操作
up(k)
down(k)
cnt是堆的大小
建堆的话只需要把前n/2的数down下来就ok
复杂度是小于O(n) 的
堆排序
#include<iostream>
using namespace std;
const int N=1e5+10;
int h[N],cnt;
void down (int k){int u=k;if(u*2<=cnt&&h[u*2]<h[k])k=u*2;if(u*2+1<=cnt&&h[u*2+1]<h[k])k=u*2+1;if(k!=u){swap(h[k],h[u]);down(k);}
}
int main(){int n,k;scanf("%d%d",&n,&k);for(int i=1;i<=n;i++)scanf("%d",&h[i]);cnt=n; //不要忘记给cnt赋值for(int i=n/2;i;i--)down(i); //建立小根堆while(k--){printf("%d ",h[1]);h[1]=h[cnt--];down(1);}return 0;
}
模拟堆
和priority_queue不同的是,这个手写的堆可以删除元素
实现的话主要是hp和ph数组,意义是heap指向point,point指向heap
双向实现
然后m代表第m个插入的数
一直维护堆的cnt,即大小
以及维护插入顺序
#include<iostream>
#include<cstring>
using namespace std;const int N=1e5+10;
int h[N],cnt,hp[N],ph[N];//hp是heap指向pointvoid heap_swap(int a,int b){swap(ph[hp[a]],ph[hp[b]]);swap(hp[a],hp[b]);swap(h[a],h[b]);
}void down(int k){int u=k;if(u*2<=cnt&&h[u*2]<h[k])k=u*2;if(u*2+1<=cnt&&h[u*2+1]<h[k])k=u*2+1;if(u!=k){heap_swap(k,u);down(k);}
}void up(int k){while(k/2&&h[k/2]>h[k]){heap_swap(k,k/2); //heap_swap用的是下标k>>=1;}
}int main(){int n,m=0;scanf("%d",&n);for(int i=0;i<n;i++){int k,x;char op[4];scanf("%s",op);if(!strcmp(op,"I")){scanf("%d",&x);m++;cnt++;h[cnt]=x;hp[cnt]=m;ph[m]=cnt;up(cnt);}else if(!strcmp(op,"PM")){printf("%d\n",h[1]);}else if(!strcmp(op,"DM")){heap_swap(1,cnt--);down(1);}else if(!strcmp(op,"D")){scanf("%d",&k);k=ph[k];heap_swap(k,cnt--);up(k);down(k);}else {scanf("%d%d",&k,&x);k=ph[k];h[k]=x;up(k);down(k);}}return 0;
}
关于字典树(trie树)
传送门
维护一颗字典树,和节点的cnt数组
总是会犯char str[N],son[N][30],cnt[N],idx;的傻逼错误
#include<iostream>using namespace std;const int N=1e5+10;
char str[N]; //别定义错了。。。
int son[N][30],cnt[N],idx;void insert(){int p=0;for(int i=0;str[i];i++){int u=str[i]-'a';if(!son[p][u])son[p][u]=++idx; //p=son[p][u];}cnt[p]++;
}int query(){int p=0;for(int i=0;str[i];i++){int u=str[i]-'a';if(!son[p][u])return 0;p=son[p][u];}return cnt[p];
}int main(){int n;scanf("%d",&n);while(n--){char op[5];scanf("%s%s",op,str);if(*op=='I'){insert();}else {printf("%d\n",query());}}return 0;
}
异或字典树
传送门
很好的字典树题目
对于每个数只需要查30次就可以找到最优解
注意节点数要是1e5*30
#include<iostream>using namespace std;
const int N=3e6+10; //
int son[N][2],idx,q[N],ans=0;void insert(int x){int p=0;for(int i=30;i>=0;i--){int &s=son[p][x>>i&1];if(!s)s=++idx;p=s;}
}
int query(int x){int p=0,res=0;for(int i=30;i>=0;i--){int s=(x>>i)&1;if(son[p][!s]){res+=1<<i; //直接把此位异或结果置为1p=son[p][!s];}else {p=son[p][s];}}return res;
}int main(){int n,res=0;scanf("%d",&n);for(int i=0;i<n;i++){int x;scanf("%d",&q[i]);insert(q[i]);}for(int i=0;i<n;i++){res=max(query(q[i]),res);}printf("%d",res);return 0;
}
关于并查集
很简单的操作
传送门
#include<iostream>
using namespace std;
const int N=1e5+10;
int ne[N];int find(int x){if(ne[x]!=x)ne[x]=find(ne[x]); //递归查找return ne[x];
}int main(){int n,m;scanf("%d%d",&n,&m);for(int i=0;i<=n;i++)ne[i]=i;//并查集初始化while(m--){int a,b;char op[2];scanf("%s%d%d",op,&a,&b);if(*op=='M'){int aa=find(a),bb=find(b);if(aa!=bb){ne[aa]=bb;}}else {int aa=find(a),bb=find(b);if(aa==bb){printf("Yes\n");}else {printf("No\n");}}}return 0;
}
传送门
这是连通块点的数量
挺简单的。。。
#include<iostream>
#include<cstring>
using namespace std;
const int N=1e5+10;
int ne[N],cnt[N];
int find(int x){if(x!=ne[x])ne[x]=find(ne[x]);return ne[x];
}int main(){int n,m;scanf("%d%d",&n,&m);for(int i=0;i<=n;i++)ne[i]=i,cnt[i]=1;while(m--){int a,b;char op[5];scanf("%s",op);if(!strcmp(op,"C")){scanf("%d%d",&a,&b);int aa=find(a),bb=find(b);if(aa!=bb){ne[aa]=bb;cnt[bb]+=cnt[aa];}}else if(!strcmp(op,"Q1")){scanf("%d%d",&a,&b);int aa=find(a),bb=find(b);if(aa==bb){printf("Yes\n");}else {printf("No\n");}}else {scanf("%d",&a);int aa=find(a);printf("%d\n",cnt[aa]);}}return 0;
}
食物链
以前做过的题,现在思路更加清晰了
主要就是存储节点与根节点的距离
根据循环关系来确定是否为谎话
#include<iostream>using namespace std;
const int N=1e5+10;
int fa[N],d[N];int find(int x){if(x!=fa[x]){int t=find(fa[x]);d[x]+=d[fa[x]];fa[x]=t;}return fa[x];
}int main(){int n,k;scanf("%d%d",&n,&k);int res=0;for(int i=0;i<=n;i++)fa[i]=i;while(k--){int op,x,y;scanf("%d%d%d",&op,&x,&y);if(x>n||y>n){res++;continue;}int px=find(x),py=find(y);if(op==1){if(px==py&&(d[x]-d[y])%3)res++;else if(px!=py){fa[px]=py;d[px]=(d[y]-d[x]);}}else {if(px==py&&(d[x]-d[y]-1)%3)res++;else if(px!=py){fa[px]=py; //吃方比被吃方距离多1d[px]+=(d[y]-d[x]+1);}}}printf("%d",res);return 0;
}
Day10 堆排序、模拟堆 trie树(字典树) 并查集相关推荐
- C++实现trie tree字典树(附完整源码)
实现trie tree字典树 实现trie tree字典树算法的完整源码(定义,实现,main函数测试) 实现trie tree字典树算法的完整源码(定义,实现,main函数测试) #include ...
- trie(字典树、前缀树)
trie(字典树.前缀树) 1. trie原理 原理 trie树,又被称为字典树.前缀树,是一种高效地存储和查找字符串集合的数据结构. 一般来说,用到trie的题目中的字母要么全是小写字母,要么全是大 ...
- HDU - 5790 Prefix(主席树+字典树)
题目链接:点击查看 题目大意:给出 n 个字符串,再给出 m 次询问,每次询问需要输出区间 [ l , r ] 内的所有字符串有多少个不同的前缀,要求算法强制在线 题目分析:统计字符串的前缀,不难想到 ...
- Algorithm:树结构(二叉树/多路查找树/字典树)的简介、具体结构(FBT/CBT/BST/BBT/Heap/Huffman、B树/B+树/R树、字典树)及其运算(增删查/遍历/旋转)、代码实现
Algorithm:树结构(二叉树/多路查找树/字典树)的简介.具体结构(FBT/CBT/BST/BBT/Heap/Huffman.B树/B+树/R树.字典树)及其运算(增删查/遍历/旋转).代码实现 ...
- Trie(前缀树/字典树)及其应用
from:https://www.cnblogs.com/justinh/p/7716421.html Trie,又经常叫前缀树,字典树等等.它有很多变种,如后缀树,Radix Tree/Trie,P ...
- Trie(字典树/前缀树)
字典树/前缀树 Trie(发音类似 "try")或者说 前缀树(字典树) 是一种树形数据结构,用于高效地存储和检索字符串数据集中的键.这一数据结构有相当多的应用情景,例如自动补完和 ...
- Luogu P2580 于是他错误的点名开始了 Trie树 字典树
字典树裸题.每次插入询问串,查询的时候拿出来直接查,信息保留在节点上. #include <bits/stdc++.h> using namespace std;char s[51]; i ...
- 【数据结构】前缀树/字典树
目录 1.概述 2.代码实现 3.应用 本文参考: LeetCode 208.实现 Trie (前缀树) 1.概述 前缀树又称字典树.Trie 树.单词查找树,是一棵有根树,同时也是一种哈希树的变种, ...
- 花神游历各国 题解(小清新线段树/树状数组+并查集)
题面 众所周知,这是一道小清新线段树 然而可以用树状数组水过去且跑得飞快 看到区间开方第一反应肯定是线段树懒标记区间修改之类的,但是这个东西似乎确凿不可维护 所以考虑暴力循环单点修改->T飞 于 ...
最新文章
- Follow Me:CCIE RS--新版CCIE Routing Switching 考纲要点
- python 常量_大疆机甲大师Python开发: 两只老虎
- 2Boost之UPD,Client and Server
- JAVA(小技巧--List)
- makefile与make
- 盘点2021年Linux界的12件大事
- 前端学习(1165):扩展运算符01
- scrapy框架的日志等级和请求传参
- VML编程之------oval圆rect矩型《VML极道教程》原著:沐缘华
- WEBFORM--第一讲
- 发那科数据服务器文件名,FANUC传输参数设置
- 基于matlab的倒立摆设计,基于MATLAB的倒立摆智能控制
- springboot + vue 搭建使用maven+ant构建
- 网吧还原软件测试简历,测试人员-斯普林网吧客户服务系统.doc
- 腾讯云人员缩减,急盈利,3000~4000 人面临被裁
- python常用方法技巧使用总结
- MAC下 生成安卓签名证书.keystore文件【详细】
- BugkuCTF misc 旋转跳跃
- 医疗IT系统在手术部供配电间的应用
- SIFT,SURF,ORB,FAST,BRISK 特征提取算法比较
热门文章
- pycharm debug 提示 Python Debugger Extension Available Cython extension speeds up Python debugging
- 手机上安装FTP服务器,通过FTP实现计算机上用FTP客户端对手机文件的无线连接访问
- mysql查询日期格式_mysql 日期格式化查询
- 几倍根号用学生计算机,几倍根号几怎么算不要网上抄的 祥细的 例如2√2 3√3 4√4 怎么算...
- 【文件格式_XML_HTML_】XML、HTML文件
- java中list删除元素_java中,删除一个List中的后n个元素
- GBase 8s 特性简介
- 【愚公系列】2021年12月 网络工程-进制转换
- 体验Vue3.0, 仿一个网易云音乐客户端
- C#实现格式转换:wmf转png