【Trie】[CQOI2016]路由表
来源:互联网 发布:会编程可以在家工作吗 编辑:程序博客网 时间:2024/05/16 16:12
题目描述
对于一次查询的一种理解方式是:无视其它所有查询操作,只看添加操作。先清空路由表,然后执行第1到a-1次添加操作。之后再执行第a到b次添加操作过程中,统计匹配改变的次数。
数据范围:
设一条表项的掩码长度为L,数据保证将目的地址转为二进制串后,末尾的32-L位均为0。
分析
在线地,每次在添加表项至路由表的时候,将该地址加入trie,然后在结束的节点标记上添加这个表项的时间。
对于每次询问,在trie上暴力匹配,然后用一个单调栈,使得能够匹配的表项出现的时间随着长度的增加而增加,最后通过二分查找找到在a,b之间改变了多少次即可。
代码
#include<cstdio>#include<algorithm>#define MAXN 1000000#define INF 0xffffffffuusing namespace std;typedef unsigned int uint;int n,cnt;struct query{ uint c; int len; inline query(){ } inline query(uint c,int len):c(c),len(len){ }}q[MAXN+10];struct node{ int pos; int ch[2];}tree[MAXN*32+10],*root=tree,*tcnt=tree;template<class T>void Read(T &x){ char c; while(c=getchar(),c!=EOF) if(c>='0'&&c<='9'){ x=c-'0'; while(c=getchar(),c>='0'&&c<='9') x=x*10+c-'0'; ungetc(c,stdin); return; }}void read(){ Read(n);}void solve(){ char s[20]; uint c,t; int len,i,a,b,best,ans; while(n--){ scanf("%s",s); if(s[0]=='A'){ c=a=0; Read(a); c=(c<<8)+a; Read(a); c=(c<<8)+a; Read(a); c=(c<<8)+a; Read(a); c=(c<<8)+a; Read(len); q[++cnt]=query(c,len); } else{ c=a=ans=0; Read(a); c=(c<<8)+a; Read(a); c=(c<<8)+a; Read(a); c=(c<<8)+a; Read(a); c=(c<<8)+a; Read(a),Read(b); best=0; for(i=1;i<a;i++){ t=INF^((1ll<<(32-q[i].len))-1); if(q[i].c==(c&t)) if(q[i].len>q[best].len) best=i; } for(;i<=b;i++){ t=INF^((1ll<<(32-q[i].len))-1); if(q[i].c==(c&t)) if(q[i].len>q[best].len) best=i,ans++; } printf("%d\n",ans); } }}int s[MAXN+10],tp;void solve2(){ char ss[20]; int a,b,len,i,x[40],pos,ans; uint c; bool d; node *p; while(n--){ scanf("%s",ss); if(ss[0]=='A'){ c=0; Read(a); c=(c<<8)+a; Read(a); c=(c<<8)+a; Read(a); c=(c<<8)+a; Read(a); c=(c<<8)+a; Read(len); p=root; for(i=31;i>=32-len;i--){ d=(c>>i)&1; if(!p->ch[d]) p->ch[d]=++tcnt-tree; p=tree+p->ch[d]; } p->pos=++cnt; } else{ len=0; Read(a); for(i=7;i>=0;i--) x[++len]=(a>>i)&1; Read(a); for(i=7;i>=0;i--) x[++len]=(a>>i)&1; Read(a); for(i=7;i>=0;i--) x[++len]=(a>>i)&1; Read(a); for(i=7;i>=0;i--) x[++len]=(a>>i)&1; Read(a),Read(b); tp=0; p=root; for(i=1;i<=32;i++){ if(p->ch[x[i]]) p=tree+p->ch[x[i]]; else break; if(p->pos&&p->pos<=b){ pos=p->pos; while(tp>0&&s[tp]>pos) tp--; s[++tp]=pos; } } ans=tp-(lower_bound(s+1,s+tp+1,a)-s)+1; printf("%d\n",ans); } }}int main(){ read(); if(n<=1000) solve(); else solve2();}
0 0
- 【Trie】[CQOI2016]路由表
- CQOI2016 路由表Route - Trie
- 【BZOJ4523】【CQOI2016】路由表 Trie
- [BZOJ4523] [CQOI2016] 路由表 - Trie - 单调栈
- BZOJ4523(Cqoi2016)[路由表]--Trie+单调栈
- [Trie树 单调栈] BZOJ 4523 [Cqoi2016]路由表
- CQOI2016 bzoj4523 路由表
- BZOJ4523 [Cqoi2016]路由表
- bzoj4523【CQOI2016】路由表
- 4523: [Cqoi2016]路由表
- bzoj 4523 [Cqoi2016]路由表
- BSoj : 4608【CQOI2016】路由表
- BZOJ 4523: [Cqoi2016]路由表
- CQOI2016题目&CQOI2016题解&不同的最小割&K远点对&手机号码&密匙破解&路由表&伪光滑数
- CQOI2016
- cqoi2016
- 路由表的结构与算法分析--trie查找
- 路由表的结构与算法分析--trie插入
- Machine Learning Logistic Regression and Newton's Method Andrew Ng 课程练习 Matlab Script 详细解析
- iOS网络编请求响应之URL结构
- Servlet技术
- Java NIO系列教程(二) Channel
- samba服务器搭建
- 【Trie】[CQOI2016]路由表
- Java并发编程:Lock
- MySQL 高可用:mysql+Lvs+Keepalived 负载均衡及故障转移
- 第9天-mysql创建高级联结
- Java NIO系列教程(一) Java NIO 概述
- 020.php
- Android学习(19) -- 数据存储之File (简单登录保存用户名和密码)
- 【机房重构】存储过程
- 正则表达式简单入门