【Trie】【树】[CQOI 2016]路由器(Route)
2016-04-10 16:22
375 查看
题目大意
由于还没有拿到题目大概先说一下题意吧:首先给你一个空空的路由器,大家然后我们对于一个空的路由表有两种操作插入一个新的IP寻址方式
查询一个IP在[L,R]中最终寻找到的IP被修改了多少次
这里IP的寻找方式是这样给出的我们有A.B.C.D四位数字外加一个L,首先我们将A.B.C.D转换为二进制,然后从A开始比较L为如果和询问的IP转换成二进制如果前面L位可以匹配我们认为这个是成功匹配的但是如果有多个成功匹配的我们取其中L最长的。
题目解析
思路非常简单,首先对于插入操作我们转换成一个二叉树,由每一个IP的01来决定位置利用AC自动机的思路,在结束位置打上标记标记IP的id同时我们寻找从根到当前插入的IP的路径上的所有点上有标记的深度最大的那一个(因为深度越大代表着L越大)然后我们将当前ID的父亲设置为找到的那个IP然后变换次数设置为他的+1这样每次插入就不会超过32次其实近似于O(log L)然后我们处理查询,首先将当前串在整个二叉树上走记录最深的节点(代表L最大)然后在L的IP的链上暴力查询[L, R]区间同理因为深度最大只有32所以也是近似于O(log L)总的复杂度就是O(nlog L)代码
#include <cstdio> #include <cstring> const int MAXN = 1000000; struct node{ int ch[2], target; }pool[MAXN*32+10]; int ecnt; struct IP{ int fa, dep; }ips[MAXN+10]; int icnt; void Insert(int *s, int L){ int u = 0, tar = 0; for(int i=0;i<L;i++){ if(!pool[u].ch[s[i]]) pool[u].ch[s[i]]=++ecnt; if(pool[u].tar) tar = pool[u].tar; u = pool[u].ch[s[i]]; } pool[u].target = ++icnt; ips[icnt].fa = tar; ips[icnt].dep = ips[tar].dep + 1; } int Query(int *s, int l, int r){ int u = 0, tar = 0; for(int i=0;i<32;i++){ if(pool[u].tar) tar = pool[u].tar; if(!pool[u].ch[s[i]]) break; u = pool[u].ch[s[i]]; } if(pool[u].tar) tar = pool[u].tar; if(tar < l) return 0; while(tar > r) tar = ips[tar].fa; int ptar = tar; while(ptar >= l) ptar = ips[ptar].fa; return ips[tar].dep - ips[ptar].dep; } int num[32]; void GetIP(int a, int b, int c, int d){ for(int i=7;i>=0;i--) num[i]=a%2, a/=2; for(int i=15;i>=8;i--) num[i]=b%2, b/=2; for(int i=23;i>=16;i--) num[i]=c%2, c/=2; for(int i=31;i>=24;i--) num[i]=d%2, d/=2; } void Read(int &u){ char ch; while(ch=getchar(), ch<'0'||ch>'9'); u = ch-'0'; while(ch=getchar(), ch>='0'&&ch<='9') u = u*10+ch-'0'; ungetc(ch, stdin); } int main(){ int n, a, b, c, d, L; scanf("%d", &n); char ord[10]; for(int i=1;i<=n;i++){ scanf("%s", ord); if(ord[0] == 'A'){ Read(a); Read(b); Read(c); Read(d); Read(L); GetIP(a,b,c,d); Insert(num, L); }else{ Read(a); Read(b); Read(c); Read(d); GetIP(a,b,c,d); Read(a); Read(b); printf("%d\n", Query(num, a, b)); } } return 0; }
相关文章推荐
- 搜狗百度360市值齐跌:搜索引擎们陷入集体焦虑?
- 本人即将筹备败家日志,敬请期待!
- IE:使用搜索助手
- C#实现获取系统目录并以Tree树叉显示的方法
- C语言实现输入一颗二元查找树并将该树转换为它的镜像
- C++深度优先搜索的实现方法
- 基于文本的搜索
- php实现搜索一维数组元素并删除二维数组对应元素的方法
- 使用Sphinx对索引进行搜索
- asp 多关键词搜索的简单实现方法
- C#使用foreach语句搜索数组元素的方法
- WordPress中用于获取搜索表单的PHP函数使用解析
- JavaScript中数组的排序、乱序和搜索实现代码
- jquery ztree实现树的搜索功能
- C#编程实现Excel文档中搜索文本内容的方法及思路
- 纯jsp打造无限层次的树代码
- sqlserver中在指定数据库的所有表的所有列中搜索给定的值
- 可以用来搜索当前页面内容的js代码
- 全文搜索和替换
- javascript搜索自动提示功能的实现第1/3页