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 ...
随机推荐
- Task 的入门
https://www.cnblogs.com/huangxincheng/archive/2012/04/03/2430638.html
- css隐藏元素
在CSS中,让元素隐藏(指屏幕范围内肉眼不可见)的方法很多,有的占据空间,有的不占据空间:有的可以响应点击,有的不能响应点击.下面一个个列出,选一个适合你的 { display: none; /* 不 ...
- ajax模仿form上传图片
<form id="iconForm"> <input class="js_upFile cover1" type="file&qu ...
- tcp文件下载客户端+服务端
客户端: import socket if __name__ == '__main__': # 创建tcp客户端socket tcp_client_socket = socket.socket(soc ...
- 交换机基础配置之单交换机划分vlan
我们以以上拓扑图为例 pc0的IP地址为:192.168.1.1 pc1的ip地址为:192.168.1.2 两台主机在同一网段,相互ping是能ping通的 我们的目的是在单交换机上划分两个vlan ...
- 精读《setState 做了什么》
1 引言 setState 是 React 框架最常用的命令,它是用来更新状态的,这也是 React 框架划时代的功能. 但是 setState 函数是 react 包导出的,他们又是如何与 reac ...
- Shell学习——终端打印
1.echo1.1.默认情况下,echo在每次调用后会添加一个换行符1.2.待打印的内容,可以用单引号.双引号或者直接打印,不同的方式,有各自的限制1.2.1.使用不带引号的echo时,没法打印分好( ...
- 学习python第十五天,面向对象
Python从设计之初就已经是一门面向对象的语言,正因为如此,在Python中创建一个类和对象是很容易的. 面向对象技术简介 类(Class): 用来描述具有相同的属性和方法的对象的集合.它定义了该集 ...
- Educational Codeforces Round 37 E. Connected Components?(图论)
E. Connected Components? time limit per test 2 seconds memory limit per test 256 megabytes input sta ...
- [BZOJ2427][HAOI2010]软件安装(tarjan+树形DP)
如果依赖关系出现环,那么对于一个环里的点,要么都选要么都不选, 所以每个环可以当成一个点,也就是强连通分量 然后就可以构造出一颗树,然后树形背包瞎搞一下就行了 注意要搞一个虚拟节点当根节点 Code ...