HDU 4760 Good Firewall ( Trie树 )
一开始看的时候就想歪了,比赛的时候一直在YY线段树区间覆盖,然后纠结节点数太多开不下怎么办啊啊啊啊……
然后昨天吃饭的时候也在纠结这到底是个啥题,后来发现公共前缀->前缀??!!!!->这不是很显然的Trie么……QAQ
举例说明:
对于subnet: 123.45.4.0/22,转化成二进制后,取前22位(长度由子网掩码决定)加入Trie树,后面的IP一定是0所以无意义,然后每个节点开一个vector保存能到达这个节点的所有子网的Pid,以及该子网IP的最大值。
对于ip_src:查找它所属于的所有子网组的Pid,并标记出来。
对于ip_dst:看它与ip_src所属的所有子网组的Pid跟之前标记出来的是否有相同的,如果有,就证明他俩在同一个子网组中。
PS.昨天晚上在杭电交一直RERERERE,改到大半夜……今天早上又看了一遍还是觉得代码没错,原样交上竟然A了……杭电你还我青春啊啊啊!!!
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <vector>
#include <algorithm> #define LL long long int using namespace std; const int MAXN = ; struct IP
{
int id;
LL num;
IP( int id, LL num ): id(id), num(num) { }
}; struct node
{
node *next[];
vector<IP> R;
node()
{
next[] = next[] = NULL;
R.clear();
}
}; node *root;
bool ok[MAXN];
int ans[MAXN];
int cas; void Insert( int mask, LL ip, int id )
{
node *p = root;
for ( int i = ; i < mask; ++i )
{
int id = ( ( ip >> ( - i) ) & ) == ? : ;
if ( p->next[id] == NULL )
{
p->next[id] = new node;
}
p = p->next[id];
}
p->R.push_back( IP( id, ip ) );
return;
} LL ReadIP()
{
int a, b, c, d;
scanf( "%d.%d.%d.%d", &a, &b, &c, &d );
LL res = ;
res |= (LL)a, res <<= ;
res |= (LL)b, res <<= ;
res |= (LL)c, res <<= ;
res |= d;
return res;
} void FindSRC( LL ip )
{
node *p = root;
for ( int i = ; i < ; ++i )
{
int id = ( ( ip >> ( - i) ) & ) == ? : ;
int sz = p->R.size();
for ( int j = ; j < sz; ++j )
{
if ( ok[ p->R[j].id ] && ( ip&( ( (1LL << (-i)) - )) ) <= p->R[j].num )
ans[ p->R[j].id ] = cas;
}
if ( p->next[id] == NULL ) return;
p = p->next[id];
}
return;
} bool FindDST( LL ip )
{
node *p = root;
for ( int i = ; i < ; ++i )
{
int id = ( ( ip >> ( - i) ) & ) == ? : ;
int sz = p->R.size();
for ( int j = ; j < sz; ++j )
{
if ( ok[ p->R[j].id ] && (ip&( ( (1LL << (-i)) - )) ) <= p->R[j].num )
{
if ( ans[ p->R[j].id ] == cas )
return true;
}
}
if ( p->next[id] == NULL ) return false;
p = p->next[id];
}
return false;
} int main()
{
//freopen( "in.txt", "r", stdin );
//freopen( "out.txt", "w", stdout );
char op[];
root = new node;
memset( ok, false, sizeof(ok) );
cas = ;
while ( scanf( "%s", op ) == )
{
if ( op[] == 'E' )
{
int id;
scanf( "%d", &id );
ok[id] = true; int n;
scanf( "%d", &n );
for ( int i = ; i < n; ++i )
{
int mask;
LL ip = ReadIP();
scanf( "/%d", &mask );
ip += ( 1LL << ( - mask) ) - ;
Insert( mask, ip, id );
}
}
else if ( op[] == 'D' )
{
int id;
scanf( "%d", &id );
ok[id] = false;
}
else
{
++cas;
LL IPsrc = ReadIP();
FindSRC( IPsrc );
LL IPdst = ReadIP();
if ( FindDST( IPdst ) ) puts("F");
else puts("D");
}
}
return ;
}
HDU 4760 Good Firewall ( Trie树 )的更多相关文章
- HDU 4757 可持久化trie树
首先如果给定一些数,询问这些数中哪个数^给定的数的值最大的话,我们可以建立一颗trie树,根连接的两条边分别为0,1,表示二进制下第15位,那么我们可以建立一颗trie树,每一条从根到叶子节点的链表示 ...
- HDU - 1251 统计难题(trie树)
Ignatius最近遇到一个难题,老师交给他很多单词(只有小写字母组成,不会有重复的单词出现),现在老师要他统计出以某个字符串为前缀的单词数量(单词本身也是自己的前缀). Input输入数据的第一部 ...
- HDU 4760 Good FireWall 完好Trie题解
本题乍看像是线段树之类的区间操作,只是由于仅仅是须要查找ip的前缀,故此事实上是使用Trie来做. 挺高难度的Trie应用,做完这道题之后说明Trie功力有一定火候了. 这里的Trie使用到了Dele ...
- hdu 1671 Phone List (Trie树)
简单的字典树应用,在建树的时候判断就行了. 需要注意的语法: 在使用malloc和free来处理动态内存的时候,仅仅是释放了这个对象所占的内存,而不会调用这个对象的析构函数:使用new和delete就 ...
- HDU 5384 Danganronpa (Trie树)
题意:给出两个集合S和T,集合中每个元素是个字符串,而T集合中任一元素都是个子弹,可以打S中的任一怪物,如果子弹是怪物的子串,那么才有伤害值1,若在怪物中出现多次,次数为该子弹打到该怪物的伤害值.每个 ...
- hdu 4825 Xor Sum trie树
Xor Sum Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 132768/132768 K (Java/Others) Proble ...
- hdu 5687 Problem C trie树
Problem C Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others) Prob ...
- hdu 1671&& poj 3630 (trie 树应用)
Phone List Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 25280 Accepted: 7678 Descr ...
- hdu 1251 统计难题(trie树入门)
统计难题 Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 131070/65535 K (Java/Others)Total Submi ...
随机推荐
- Linux操作系统下的三种Java环境配置方法
方法1:修改/etc/profile 文件 所有用户的 shell都有权使用这些环境变量 (1)在 shell终端执行命令:vi /etc/profile (2)在 profile文件末尾加入: e ...
- 第10章 新建工程-库函数版—零死角玩转STM32-F429系列
第10章 新建工程—库函数版 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.youku.com/fire ...
- Oracle 启动 停止JOB
转自:https://www.cnblogs.com/qianbing/p/6971633.html --查看job下次执行时间以及间隔时间 '; --启动job ); --停用job EXEC DB ...
- 小程序navigateTo和redirectTo的使用
最近公司商城项目,有个小问题,就是在商品详情页>购物车页>确认下单页>支付成功和取消支付都会前往订单详情页.当时我没想这么多就全部跳转都用了navigateTo,这样做的话,第一个问 ...
- hdu_1573_X问题 (分段之中国剩余
求在小于等于N的正整数中有多少个X满足:X mod a[0] = b[0], X mod a[1] = b[1], X mod a[2] = b[2], …, X mod a[i] = b[i], … ...
- mysql 自增主键为什么不是连续的?
由于自增主键可以让主键索引尽量地保持递增顺序插入,避免了页分裂,因此索引更紧凑 MyISAM 引擎的自增值保存在数据文件中 nnoDB 引擎的自增值,其实是保存在了内存里,并且到了 MySQL 8.0 ...
- docker镜像文件导入与导出 , 支持批量
1. 查看镜像id sudo docker images REPOSITORY TAG IMAGE ID CREATED SIZE quay.io/calico/node v1.0.1 c70511a ...
- Shell学习——数组
1.普通数组:只能用整数作为索引1.1.赋值[root@client02 ~]# array[0]=test1[root@client02 ~]# array[1]=test2[root@client ...
- 图解HTTP总结(2)——简单的HTTP协议
HTTP协议是一种不保存状态,即无状态(stateless)协议.HTTP协议自身不对请求和响应之间的通信状态进行保存.也就是说在HTTP这个级别,协议对于发送过的请求或响应都不做持久化处理. 使用H ...
- Python 中关于文件操作的注意事项
文件操作 #打开文件 f = open('要打开的文件路径',mode = 'r/w/a', encoding = '文件原来写入时的编码') #操作 data = f.read() #读取 f.wr ...