Good Firewall(字典树 HDU4760)
Good Firewall
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 713 Accepted Submission(s): 203
Problem Description
Professor X is an expert in network security. These days, X is planning to build a powerful network firewall, which is called Good Firewall (a.k.a., GFW). Network flows enter in the GFW will be forwarded or dropped according to pre-established forwarding policies.
Basically, a forwarding policy P is a list of IP subnets, {ip_subnet_1, …, ip_subnet_n}. If P is enabled in GFW, a network flow F with source and destination IP address both located in P can be accepted and forwarded by GFW, otherwise F will be dropped by GFW.
You may know that, an IP address is a 32-bit identifier in the Internet, and can be written as four 0~255 decimals. For example, IP address 01111011.00101101.00000110.01001110 can be expressed as 123.45.6.78. An IP subnet is a block of adjacent IP address with the same binary prefix, and can be written as the first IP address in its address block together with the length of common bit prefix. For example, IP subnet 01111011.00101101.00000100.00000000/22 (123.45.4.0/22) is an IP subnet containing 1024 IP addresses, starting from 123.45.4.0 to 123.45.7.255. If an IP address is in the range of an IP subnet, we say that the IP address is located in the IP subnet. And if an IP address is located in any IP subnet(s) in a policy P, we say that the IP address is located in the policy P.
How will you design the GFW, if you take charge of the plan?
Input
The input file contains no more than 32768 lines. Each line is in one of the following three formats:
E id n ip_subnet_1 ip_subnet_2 … ip_subnet_n
D id
F ip_src ip_dst
The first line means that a network policy Pid (1<=id<=1024) is enabled in GFW, and there are n (1<=n <=15) IP subnets in Pid. The second line means that policy Pid (which is already enabled at least once) is disabled in GFW. The last line means that a network flow with source and destination IP address is entered in GFW, and you need to figure out whether GFW is going to forward (F) or drop (D) this flow:
If the source and destination IP address both are located in one of enabled policy group Pid, GFW will forward this flow.
Otherwise GFW will drop this flow. That is, if the source or destination IP address is not located in any of enabled policy group, or they are only located in different enabled policy group(s), GFW will drop it.
IP subnets can be overlapped. An IP address may or may not be located in any policy group, and can also be located in multiple policy groups.
In the global routing table, most of the IP subnets have at least 2^8 IP addresses, and at most 2^24 IP addresses. In our dataset, every IP subnet has a prefix length between 8 and 24.
Output
For each ‘F’ operation, output a single ‘F’ (forward) or ‘D’ (drop) in a single line. Just see the sample output for more detail.
Sample Input
E 1 2 123.45.4.0/22 123.45.8.0/22
F 123.45.4.1 123.45.8.1
F 123.45.8.1 123.45.4.1
E 2 1 123.45.6.0/24
D 1
F 123.45.6.123 123.45.6.234
F 123.45.8.1 123.45.4.1
Sample Output
F
F
F
D
字典树的好题
题目大意:有一个防火墙,具有添加一个子网络,删除一个子网络,以及转发包的操作。
添加操作包含子网络的id,以及子网络的子网掩码(计算出网络前缀,以及ip的下限),不会超过15个。
删除则是给定要删除的子网络id。
转发操作,给定两个ip,如果两个ip在同一个子网络中,则可以转发,否则丢弃。
解题思路:对子网掩码前缀建立字典树,每个前缀终止节点用一个set记录属于哪些子网络,ip下限。那么增加和删除操作既可以解决了。对于查询操作,分别查询两个ip,处理除两个ip可能属于的网络,判断有无共同即可。
#include <map>
#include <set>
#include <queue>
#include <cstring>
#include <string>
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
struct Trie
{
int next[2];
vector<int>vec;
} st[1024*15*32+1000];
int top;
struct IP
{
int n;
LL res[20];
int len[20];
} sub[1200];
LL bite[40];
char str[110];
int Creat()
{
memset(st[top].next,-1,sizeof(st[top].next));
st[top].vec.resize(0);
return top++;
}
void Insert(int Root,int len,int id, LL res)
{
for(int i=1; i<=len; i++)
{
int ans=(bite[32-i]&res)?1:0;
if(st[Root].next[ans]==-1)
{
st[Root].next[ans]=Creat();
}
Root=st[Root].next[ans];
}
st[Root].vec.push_back(id);
}
void Delete(int id,int len,LL res,int Root)
{
for(int i=1; i<=len; i++)
{
Root=st[Root].next[(res&bite[32-i])?1:0];
}
for(vector<int>::iterator it=st[Root].vec.begin(); it!=st[Root].vec.end(); it++)
{
if(*it==id)
{
*it=0;
break;
}
}
}
bool vis[1050];
bool Query(LL res,int num,int Root)
{
vector<int>::iterator it;
for(int i=1; i<=32; i++)
{
for(it = st[Root].vec.begin(); it!=st[Root].vec.end(); it++)
{
if(*it == 0)
{
continue;
}
if(num==1)
{
vis[*it] = true;
}
else
{
if(vis[*it])
{
return true;
}
}
}
int ans=(bite[32-i]&res)?1:0;
if(st[Root].next[ans]==-1)
{
return false;
}
Root = st[Root].next[ans];
}
for(it=st[Root].vec.begin(); it != st[Root].vec.end(); it++)
{
if(*it==0)
{
continue;
}
if(num==1)
{
vis[*it]=true;
}
else
{
if(vis[*it])
{
return true;
}
}
}
return false;
}
int main()
{
top=0;
int a,b,c,d,len;
int Root = Creat();
char s[3];
int id,n;
bite[0]=1;
for(int i=1; i<=40; i++)
{
bite[i]=bite[i-1]<<1;
}
while(~scanf("%s",s))
{
if(s[0]=='E')
{
scanf("%d %d",&id,&n);
sub[id].n=n;
for(int i=1; i<=n; i++)
{
scanf("%s",str);
sscanf(str,"%d.%d.%d.%d/%d",&a,&b,&c,&d,&len);
LL res = a*256LL*256LL*256LL+b*256LL*256LL+c*256LL+d;
sub[id].res[i]=res;
sub[id].len[i]=len;
Insert(Root,len,id,res);
}
}
else if(s[0]=='D')
{
scanf("%d",&id);
for(int i=1; i<=sub[id].n; i++)
{
Delete(id,sub[id].len[i],sub[id].res[i],Root);
}
}
else if(s[0]=='F')
{
scanf("%s",str);
sscanf(str,"%d.%d.%d.%d",&a,&b,&c,&d);
memset(vis,false,sizeof(vis));
Query(a*256LL*256LL*256LL+b*256LL*256LL+c*256LL+d,1,Root);
scanf("%s",str);
sscanf(str,"%d.%d.%d.%d",&a,&b,&c,&d);
if(Query(a*256LL*256LL*256LL+b*256LL*256LL+c*256LL+d,2,Root))
{
printf("F\n");
}
else
{
printf("D\n");
}
}
}
return 0;
}
Good Firewall(字典树 HDU4760)的更多相关文章
- 萌新笔记——用KMP算法与Trie字典树实现屏蔽敏感词(UTF-8编码)
前几天写好了字典,又刚好重温了KMP算法,恰逢遇到朋友吐槽最近被和谐的词越来越多了,于是突发奇想,想要自己实现一下敏感词屏蔽. 基本敏感词的屏蔽说起来很简单,只要把字符串中的敏感词替换成"* ...
- [LeetCode] Implement Trie (Prefix Tree) 实现字典树(前缀树)
Implement a trie with insert, search, and startsWith methods. Note:You may assume that all inputs ar ...
- 字典树+博弈 CF 455B A Lot of Games(接龙游戏)
题目链接 题意: A和B轮流在建造一个字,每次添加一个字符,要求是给定的n个串的某一个的前缀,不能添加字符的人输掉游戏,输掉的人先手下一轮的游戏.问A先手,经过k轮游戏,最后胜利的人是谁. 思路: 很 ...
- 萌新笔记——C++里创建 Trie字典树(中文词典)(一)(插入、遍历)
萌新做词典第一篇,做得不好,还请指正,谢谢大佬! 写了一个词典,用到了Trie字典树. 写这个词典的目的,一个是为了压缩一些数据,另一个是为了尝试搜索提示,就像在谷歌搜索的时候,打出某个关键字,会提示 ...
- 山东第一届省赛1001 Phone Number(字典树)
Phone Number Time Limit: 1000ms Memory limit: 65536K 有疑问?点这里^_^ 题目描述 We know that if a phone numb ...
- 字典树 - A Poet Computer
The ACM team is working on an AI project called (Eih Eye Three) that allows computers to write poems ...
- trie字典树详解及应用
原文链接 http://www.cnblogs.com/freewater/archive/2012/09/11/2680480.html Trie树详解及其应用 一.知识简介 ...
- HDU1671 字典树
Phone List Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
- *HDU1251 字典树
统计难题 Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 131070/65535 K (Java/Others)Total Submi ...
随机推荐
- 64位虚拟机安装64位ubuntu出现问题
virtualbox 出现this kernel requires an an x86-64 cpu 错误 如题,但是主机是win8 64位,使用virtualbox安装ubuntu-12.04.3- ...
- html 抽奖代码
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- mysql语句中有引号的问题解决方案
在mysql的查询.修改.插入.删除的sql语句里有引号如何处理? 例如: <? $name = "my name is xcxc"; $people = "i'm ...
- Bootstrap (导航、标签、面包屑导航)
导航 Bootstrap中可用的导航有相似的标记,用基类.nav开头,这是相似的部分.改变修饰类可以改变样式. <!DOCTYPE html> <html> <head& ...
- BizTalk动手实验(四)Schema开发测试
1 课程简介 通过本课程熟悉Schema的相关开发技术 2 准备工作 1. 熟悉XML.XML Schema.XSLT等相关XML开发技术 2. 新建BizTalk空项目 3 演示 3.1 格式化XM ...
- 【iCore3双核心板】【4.3寸液晶驱动板爆照!】
[源代码完全开源,过几天连同硬件一起发布] 花了好久的时间,我们的fpga工程师才完成这液晶模块的驱动代码,其核心价值如下: 1.完全基于fpga驱动,sdram当做缓存: 2.内建双缓冲机制:方便 ...
- Asp.net DropDownList 自定义样式(想怎么改就怎么改!)
最近在做一个asp.net的项目,需要对默认的dropdownlist样式进行美化,固有的dropdownlist的小箭头实在让人无法接受,于是开始在百度,google 上下求索,天不负有心人,终于找 ...
- 通过方法名(字符串)执行Objective-C方法
SEL selector = NSSelectorFromString(@"方法名"); if ([self respondsToSelector:selector]){ //判断 ...
- PHP检测移动设备类mobile detection使用实例
目前,一个网站有多个版本是很正常的,如PC版,3G版,移动版等等.根据不同的浏览设备我们需要定向到不同的版本中.不仅如此,我们有时候还需要根据不同的客户端加载不同的CSS,因此我们需要能够检测浏览设备 ...
- block(代码块)的介绍以及使用方法和变量之间的关系
http://blog.csdn.net/menxu_work/article/details/8762848 block(代码块)的介绍以及使用方法和变量之间的关系 block(代码块)的介绍以及使 ...