hdu 4760 - Good Firewall(Trie)
2015-07-08 23:30
651 查看
Good Firewall
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 663 Accepted Submission(s): 177
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
思路:将每个子网按照前缀加进去,这里要注意,因为子网是可以overlap的,所以用vector存一下(略坑),然后每次询问,在树上走一遍就行了。
[code]#include<iostream> #include<cstdio> #include<string> #include<cstring> #include<vector> #include<cmath> #include<queue> #include<stack> #include<map> #include<set> #include<algorithm> using namespace std; const int maxn=40000; int ip[40]; int a[5]; bool vis[1025]; vector<int> ans1,ans2; void encode() { for(int i=0;i<4;i++) { for(int j=i*8+7;j>=i*8;j--) ip[j]=a[i]%2,a[i]>>=1; } } struct Trie { int ch[maxn][2]; vector<int> val[maxn]; int sz; void clear(){memset(ch[0],0,sizeof(ch[0]));sz=1;} int idx(char x){return x-'0';} void insert(int *ip,int len,int id) { int u=0; for(int i=0;i<len;i++) { int c=ip[i]; if(!ch[u][c]) { memset(ch[sz],0,sizeof(ch[sz])); val[sz].clear(); ch[u][c]=sz++; } u=ch[u][c]; } val[u].push_back(id); } void find(vector<int> &ans) { int u=0; for(int i=0;i<32;i++) { int c=ip[i]; if(!ch[u][c])return ; u=ch[u][c]; int len=val[u].size(); for(int j=0;j<len;j++) { int v=val[u][j]; if(!vis[v])ans.push_back(v); } } } }tree; int main() { char op[5]; int id,n; int subnet; tree.clear(); while(scanf("%s",op)!=EOF) { if(op[0]=='E') { scanf("%d%d",&id,&n); for(int i=1;i<=n;i++) { char tmp; for(int j=0;j<4;j++) scanf("%d%c",&a[j],&tmp); scanf("%d",&subnet); encode(); tree.insert(ip,subnet,id); } vis[id]=0; } else if(op[0]=='D') { scanf("%d",&id); vis[id]=1; } else { char tmp; ans1.clear(),ans2.clear(); for(int j=0;j<4;j++) scanf("%d%*c",&a[j],&tmp); encode(); tree.find(ans1); for(int j=0;j<4;j++) scanf("%d%*c",&a[j],&tmp); encode(); tree.find(ans2); sort(ans1.begin(),ans1.end()); sort(ans2.begin(),ans2.end()); int flag=false; int i=0,j=0; while(i<ans1.size()&&j<ans2.size()) { if(ans1[i]==ans2[j]) { flag=true; break; } else if(ans1[i]>ans2[j])j++; else i++; } if(flag)printf("F\n"); else printf("D\n"); } } return 0; }
相关文章推荐
- 科技企业是员工的最佳“父母”?
- POJ 1003:Hangover
- POJ 1003:Hangover
- AC GO GO GO!!!
- Algorithm --> 邮票连续组合问题
- Scrapy的Ip代理的配置(未完成)
- freemarker XMLGregorianCalendar 转日期
- Django项目国际化
- GooFlow
- Algorithm --> 字母重排
- Django静态文件配置
- 总结Django中的用户权限模块
- Mongo库表操作命令
- [翻译]Go语言调度器
- 让乐视如此优惠电信欢go怎么做到的
- 关于&nbsp;空格实体在最新的IE、Firefox和Google Chrome浏览器中解析宽度不一致问题的解决
- Algorithm --> 6174问题
- Go home or stand up
- GO语言使用开源SSH模拟终端
- Why we need model on Django ?