一开始看的时候就想歪了,比赛的时候一直在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树 )的更多相关文章

  1. HDU 4757 可持久化trie树

    首先如果给定一些数,询问这些数中哪个数^给定的数的值最大的话,我们可以建立一颗trie树,根连接的两条边分别为0,1,表示二进制下第15位,那么我们可以建立一颗trie树,每一条从根到叶子节点的链表示 ...

  2. HDU - 1251 统计难题(trie树)

    Ignatius最近遇到一个难题,老师交给他很多单词(只有小写字母组成,不会有重复的单词出现),现在老师要他统计出以某个字符串为前缀的单词数量(单词本身也是自己的前缀).  Input输入数据的第一部 ...

  3. HDU 4760 Good FireWall 完好Trie题解

    本题乍看像是线段树之类的区间操作,只是由于仅仅是须要查找ip的前缀,故此事实上是使用Trie来做. 挺高难度的Trie应用,做完这道题之后说明Trie功力有一定火候了. 这里的Trie使用到了Dele ...

  4. hdu 1671 Phone List (Trie树)

    简单的字典树应用,在建树的时候判断就行了. 需要注意的语法: 在使用malloc和free来处理动态内存的时候,仅仅是释放了这个对象所占的内存,而不会调用这个对象的析构函数:使用new和delete就 ...

  5. HDU 5384 Danganronpa (Trie树)

    题意:给出两个集合S和T,集合中每个元素是个字符串,而T集合中任一元素都是个子弹,可以打S中的任一怪物,如果子弹是怪物的子串,那么才有伤害值1,若在怪物中出现多次,次数为该子弹打到该怪物的伤害值.每个 ...

  6. hdu 4825 Xor Sum trie树

    Xor Sum Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 132768/132768 K (Java/Others) Proble ...

  7. hdu 5687 Problem C trie树

    Problem C Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Prob ...

  8. hdu 1671&& poj 3630 (trie 树应用)

    Phone List Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 25280   Accepted: 7678 Descr ...

  9. hdu 1251 统计难题(trie树入门)

    统计难题 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131070/65535 K (Java/Others)Total Submi ...

随机推荐

  1. 关于VMware给系统分区扩容的一点经验

    我的VMware版本是8.0.6 build-1035888,里面安装的是Windows XP SP3 首先,在VM关机状态下使用Hard disk设置中的Utilities下的Expand给整个磁盘 ...

  2. linux中CURL的安装

    curl是一款著名的字符界面下的下载工具,支持HTTP.HTTPS.FTP.FTPS.DICT.TELNET.LDAP.FILE,和GOPHER.此外还具有cookies支持.断点续传.FTP上传.密 ...

  3. 【转】基于JavaMail的Java邮件发送

    http://blog.csdn.net/xietansheng/article/details/51673073 http://blog.csdn.net/xietansheng/article/d ...

  4. 在c#中using和new这两个关键字有什么意义?

    在c#中using和new这两个关键字有什么意义?答:using 引入名称空间或者使用非托管资源, new 新建实例或者隐藏基类方法

  5. NestedScrollView和RecyclerView使用,并设置间距

    NestedScrollView和RecyclerView使用,并设置间距: 效果图如下: 1.NestedScrollView 和RecyclerView嵌套问题(类似ScrollView 和lis ...

  6. javabeans 内省 introspector BeanUtils

    javaBeans 属性的概念 不只是字段,而是其get set 方法 且该get方法有返回值的称为属性,继承Object类的getClass方法 package com.swift.demo1; p ...

  7. 微信小程序之setData原理以及几点关于小程序的吐槽

    小程序不方便之处: 1: 想做个获取列表中每个item所在的对应滚动条的高度在哪里,或者元素本身的高度也不好获取,极其不方便,网上看的别人做的滚动条相关的,都是写死或者已知的item高度,目前没找到正 ...

  8. vscode + leetcode +github 同步

    1.用VScode打开本地leetcode文件夹 C:\Users\Administrator\.leetcode 2.上传到本地git库 3.打开github桌面,上传到远程库

  9. Servlet学习笔记05——什么是jsp?

    1. jsp (java server page) (1)jsp是什么? sun公司制订的一种服务器端动态页面技术规范. 注: 因为虽然使用servlet也可以生成动态页面, 但是过于繁琐(需要使用o ...

  10. PHP自动生成分页链接

    page.class.php <?php class Page { // 分页栏每页显示的页数 public $rollPage = 5; // 页数跳转时要带的参数 public $param ...