zoukankan      html  css  js  c++  java
  • 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 = 1028;
    
    struct IP
    {
        int id;
        LL num;
        IP( int id, LL num ): id(id), num(num) { }
    };
    
    struct node
    {
        node *next[2];
        vector<IP> R;
        node()
        {
            next[0] = next[1] = 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 = 0; i < mask; ++i ) { int id = ( ( ip >> (31 - i) ) & 1 ) == 1 ? 1 : 0; 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 = 0; res |= (LL)a, res <<= 8; res |= (LL)b, res <<= 8; res |= (LL)c, res <<= 8; res |= d; return res; } void FindSRC( LL ip ) { node *p = root; for ( int i = 0; i < 32; ++i ) { int id = ( ( ip >> (31 - i) ) & 1 ) == 1 ? 1 : 0; int sz = p->R.size(); for ( int j = 0; j < sz; ++j ) { if ( ok[ p->R[j].id ] && ( ip&( ( (1LL << (31-i)) - 1 )) ) <= 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 = 0; i < 32; ++i ) { int id = ( ( ip >> (31 - i) ) & 1 ) == 1 ? 1 : 0; int sz = p->R.size(); for ( int j = 0; j < sz; ++j ) { if ( ok[ p->R[j].id ] && (ip&( ( (1LL << (31-i)) - 1 )) ) <= 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[4]; root = new node; memset( ok, false, sizeof(ok) ); cas = 0; while ( scanf( "%s", op ) == 1 ) { if ( op[0] == 'E' ) { int id; scanf( "%d", &id ); ok[id] = true; int n; scanf( "%d", &n ); for ( int i = 0; i < n; ++i ) { int mask; LL ip = ReadIP(); scanf( "/%d", &mask ); ip += ( 1LL << (32 - mask) ) - 1; Insert( mask, ip, id ); } } else if ( op[0] == '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 0; }
  • 相关阅读:
    日志统计|2018年蓝桥杯B组题解析第八题-fishers
    螺旋折线|2018年蓝桥杯B组题解析第七题-fishers
    递增三元组|2018年蓝桥杯B组题解析第六题-fishers
    乘积尾零|2018年蓝桥杯B组题解析第三题-fishers
    明码|2018年蓝桥杯B组题解析第二题-fishers
    第几天|2018年蓝桥杯B组题解析第一题-fishers
    2016年蓝桥杯B组C/C++省赛(预选赛)题目解析
    2016年蓝桥杯B组C/C++省赛(预选赛)试题
    计蒜客习题:同余方程
    数论——同余方程
  • 原文地址:https://www.cnblogs.com/GBRgbr/p/3345167.html
Copyright © 2011-2022 走看看