CQOI2016 路由表Route - Trie

这里写图片描述

这里写图片描述

这里写图片描述

分析:

正解是Trie吧。考完之后想想真的是这样,题目还明确说了不会添加目的地址和掩码长度都一样的项,那么对于每一个01串建立Trie树,在相应掩码结束的位置记录这个串位于添加表中的位置pos。每次询问的时候扫一遍Trie对应询问的串,对每一个扫过的位置上记录的pos排序(最多32个,不会超时)。按照题目的要求模拟一下,算出答案。

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define MAXN 1000000

struct node{
    int pos,len;
}b[MAXN+10];

int n,a[MAXN+10][5],qua[MAXN+10][5],cnta,cntq;
int Trie[MAXN*32+10][2],cntu,root,pos[MAXN*32+10],cntb;

void read()
{
    char opt[20],str[100];
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%s",opt);
        if(opt[0]=='A'){
            scanf("%s",str);
            int val=0,L=0,lens=strlen(str);
            for(int i=0;i<lens;i++){
                if(i&&str[i-1]=='/'){
                    for(;i<lens;i++)
                        L=L*10+str[i]-'0';
                    break;
                }
                int t=0;
                for(;str[i]!='.'&&str[i]!='/'&&i<lens;i++)
                    t=t*10+str[i]-'0';
                val=val*256+t;
            }
            ++cnta;
            a[cnta][0]=val,a[cnta][1]=L;
        }
        else{
            ++cntq;
            scanf("%s%d%d",str,&qua[cntq][1],&qua[cntq][2]);
            int lens=strlen(str),val=0;
            for(int i=0;i<lens;i++){
                int t=0;
                for(;str[i]!='.'&&i<lens;i++)
                    t=t*10+str[i]-'0';
                val=val*256+t;
            }
            qua[cntq][0]=val;
        }
    }
}
void Insert(char *str,int len,int id)
{
    int t=root;
    for(int i=0;i<len;i++){
        if(!Trie[t][str[i]-'0'])
            Trie[t][str[i]-'0']=++cntu;
        t=Trie[t][str[i]-'0'];
    }
    pos[t]=id;
}
void Build()
{
    char str[100];
    memset(str,0,sizeof str);
    for(int i=1;i<=cnta;i++){
        for(int j=0;j<32;j++)
            str[31-j]=(a[i][0]&(1<<j))?'1':'0';
        Insert(str,a[i][1],i);
    }
}
bool cmp(node a0,node b0){
    return a0.pos<b0.pos;
}
void workout()
{
    char str[100];
    memset(str,0,sizeof str);
    for(int i=1;i<=cntq;i++){
        for(int j=0;j<32;j++)
            str[31-j]=(qua[i][0]&(1<<j))?'1':'0';
        int t=root,ans=0;
        cntb=0;
        for(int j=0;j<32;j++){
            if(!Trie[t][str[j]-'0'])
                break;
            t=Trie[t][str[j]-'0'];
            if(pos[t]&&pos[t]<=qua[i][2]){
                ++cntb;
                b[cntb].pos=pos[t];
                b[cntb].len=j+1;
            }
        }
        sort(b+1,b+cntb+1,cmp);
        int pnt=-1;
        for(int j=1;j<=cntb;j++)
            if(pnt<b[j].len){
                pnt=b[j].len;
                if(b[j].pos>=qua[i][1])
                    ans++;
            }
        printf("%d\n",ans);
    }
}
int main()
{
    //freopen("route.in","r",stdin);
    //freopen("route.out","w",stdout);

    read();
    Build();
    workout();
    return 0;
}
posted @ 2016-04-11 15:26  KatarinaYuan  阅读(260)  评论(0编辑  收藏  举报