zoukankan      html  css  js  c++  java
  • HDU 4760 字典树(题意比较难理解)

    题目大意:有多个政策,每个政策里面有很多子网,E 表示加入一个政策,D表示禁止一个政策,F就是询问ip1,ip2是不是在同一个政策中。

    思路:子网有个特点前缀相同,对于E操作,不难想到用字典树来维护所有子网(即ip的前缀),每个节点用一个vector保存该子网(即前缀)所属于的所有政策的标号。对于D操作,我们用一个数组维护该政策可不可用,对于F就是先把ip1所在的政策做一下标记,然后让ip2所在的政策有没有在这些标记中的即可。

    //#pragma comment(linker, "/STACK:102400000")
    #include<cstdlib>
    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<algorithm>
    #include<set>
    #include<map>
    #include<list>
    #include<queue>
    #include<vector>
    #define tree int o,int l,int r
    #define lson o<<1,l,mid
    #define rson o<<1|1,mid+1,r
    #define lo o<<1
    #define ro o<<1|1
    #define pb push_back
    #define mp make_pair
    #define ULL unsigned long long
    #define LL long long
    #define inf 0x7fffffff
    #define eps 1e-7
    #define N 109
    using namespace std;
    int m,n,T,t;
    char str[10];
    int ch[800000][2],sz,id,len,ncase;
    vector<int> g[800000];
    int vis[1125],f[1125];
    void init()
    {
        sz=1;
        memset(ch[0],0,sizeof(ch[0]));
    }
    LL readip()
    {
        int a,b,c,d;
        scanf("%d.%d.%d.%d",&a,&b,&c,&d);
        LL ans=0;
        ans+=a;ans<<=8;
        ans+=b;ans<<=8;
        ans+=c;ans<<=8;
        ans+=d;
        return ans;
    }
    void insert(LL ip,int len,int id)
    {
        int u=0;
        for(int i=31,j=0;j<len;j++,i--)
        {
            int c=(ip>>i)&1;
            if(ch[u][c]==0)
            {
                ch[u][c]=sz++;
            }
            u=ch[u][c];
        }
        g[u].push_back(id);
    }
    void fun(LL ip)
    {
        int u=0;
        for(int i=31;i>=0;i--)
        {
            int c=(ip>>i)&1;
            if(ch[u][c]==0)
            {
                break;
            }
            u=ch[u][c];
            for(int j=0;j<g[u].size();j++)
            if(vis[g[u][j]])
            f[g[u][j]]=ncase;
        }
    }
    int solve(LL ip)
    {
        int u=0;
        for(int i=31;i>=0;i--)
        {
            int c=(ip>>i)&1;
            if(ch[u][c]==0)
            {
                break;
            }
            u=ch[u][c];
            for(int j=0;j<g[u].size();j++)
            if(vis[g[u][j]]&&f[g[u][j]]==ncase)
            return 1;
        }
        return 0;
    }
    int main()
    {
    #ifndef ONLINE_JUDGE
        freopen("ex.in","r",stdin);
    #endif
        init();
        while(scanf("%s",str)==1)
        {
            if(str[0]=='E')
            {
                scanf("%d%d",&id,&n);
                vis[id]=1;
                for (int i=0;i<n;++i )
                {
                    LL ip=readip();
                    scanf("/%d",&len);
                    insert(ip,len,id);
                }
            }
            else if(str[0]=='D')
            {
                scanf("%d",&id);
                vis[id]=0;
            }
            else
            {
                ncase++;
                LL ip1=readip();
                LL ip2=readip();
                fun(ip1);
                puts(solve(ip2)?"F":"D");
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    微信小程序@bindgetuserinfo @bindgetphonenumber
    报错总结
    前端面试题
    关于vue ssr next服务端渲染
    【012】JavaSE面试题(十二):多线程(2)
    【011】JavaSE面试题(十一):多线程(1)
    [010]
    [009]
    [008]
    添加Lombok插件后调用Setter或Getter方法IDEA编译错误
  • 原文地址:https://www.cnblogs.com/sbaof/p/3363997.html
Copyright © 2011-2022 走看看