hdu 4760 - Good Firewall(Trie)

原创 2015年07月08日 23:30:42

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:

  1. If the source and destination IP address both are located in one of enabled policy group Pid, GFW will forward this flow.

  2. 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存一下(略坑),然后每次询问,在树上走一遍就行了。

#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;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。

hdu3001Travelling (状态压缩DP,三进制)

Travelling Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total ...
  • u010372095
  • u010372095
  • 2014年08月10日 22:01
  • 1416

HDU 1277 全文检索 (Trie树应用 好题)

HDU 1277 全文检索 (trie树应用 好题)
  • Tc_To_Top
  • Tc_To_Top
  • 2015年02月23日 23:32
  • 1151

hdu 4757 Tree(可持久化字典树)

题目链接:hdu 4757 Tree 题目大意:给定一棵树,每个节点有一个值,现在有Q次询问,每次询问u到v路径上节点值与w亦或值的最大值。 解题思路:刚开始以为是树链剖分,其实树链剖分只是用来求...
  • u011328934
  • u011328934
  • 2014年10月30日 18:27
  • 2524

hdu4760Good Firewall(Trie树)

题目链接:点击打开链接 题意描述:现有一个网络中,在不同的子网之间建立转发策略,有相同的转发策略的子网之间可以互相通信 给出以下三种操作: 操作一:E  可以理解为建立标号为id的转发策略,有n...
  • mengxingyuanlove
  • mengxingyuanlove
  • 2015年08月22日 16:00
  • 497

hdu 1847 Good Luck in CET-4 Everybody! 巴什博弈??我分不太清啦,水之~

Problem Description 大学英语四级考试就要来临了,你是不是在紧张的复习?也许紧张得连短学期的ACM都没工夫练习了,反正我知道的Kiki和Cici都是如此。当然,作为在考场浸润了十几载...
  • Lionel_D
  • Lionel_D
  • 2015年02月26日 17:54
  • 602

hdu4722 Good Numbers 规律题

Good Numbers Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Tot...
  • EventQueue
  • EventQueue
  • 2016年04月11日 21:29
  • 321

hdu 1850 Being a Good Boy in Spring Festival (博弈)

经典的博弈题啊,必须弄懂必败点条件。这里是对n堆的牌数去异或,如果值为0则表示必败。题目问我们第一布有哪几种方法胜利。 即就是第一步能够给对手构建多少个必败点。 由于一次只能对一堆排进行操作,假设...
  • nealgavin
  • nealgavin
  • 2012年04月04日 09:52
  • 411

HDU1850 Being a Good Boy in Spring Festival Nim博弈

题目链接:HDu1850 Being a Good Boy in Spring Festival Time Limit: 1000/1000 MS (Java/Others)    Mem...
  • qq_29480875
  • qq_29480875
  • 2016年08月30日 20:40
  • 120

HDU 1850 - Being a Good Boy in Spring Festival【Nim博弈】

Being a Good Boy in Spring Festival Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/3...
  • lututu123
  • lututu123
  • 2016年12月20日 19:01
  • 144

【hdu 1847】Good Luck in CET-4 Everybody!

Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submissio...
  • harlow_cheng
  • harlow_cheng
  • 2016年12月30日 17:14
  • 123
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:hdu 4760 - Good Firewall(Trie)
举报原因:
原因补充:

(最多只允许输入30个字)