• 【LOJ】#2046. 「CQOI2016」路由表


    题解

    题面太长无法阅读系列……

    这里说的选择改变指的是在下面区间里碰上了一个更长的可匹配的地址,如果可匹配但是匹配长度没有当前的值大,那么不算改变

    我们建一个可持久化的trie,查询的时候先在前(a - 1)个里找到最长的可以得到的地址

    然后再在区间的trie里找到那条链上,如果碰到一个结束点且比我们初始长度大的路径串,就丢进一个栈里,维护栈的递增

    最后栈的长度就是答案

    代码

    #include <bits/stdc++.h>
    #define enter putchar('
    ')
    #define space putchar(' ')
    #define pii pair<int,int>
    #define fi first
    #define se second
    #define MAXN 1000005
    #define pb push_back
    #define mp make_pair
    #define eps 1e-8
    //#define ivorysi
    using namespace std;
    typedef long long int64;
    typedef double db;
    template<class T>
    void read(T &res) {
        res = 0;T f = 1;char c = getchar();
        while(c < '0' || c > '9') {
            if(c == '-') f = -1;
            c = getchar();
        }
        while(c >= '0' && c <= '9') {
            res = res * 10 + c - '0';
            c = getchar();
        }
        res *= f;
    }
    template<class T>
    void out(T x) {
        if(x < 0) {x = -x;putchar('-');}
        if(x >= 10) out(x / 10);
        putchar('0' + x % 10);
    }
    int M;
    char s[35];
    struct node {
        int son[2],siz,ed;
    }tr[MAXN * 32];
    int Ncnt,rt[MAXN],cnt;
    int sta[MAXN],top;
    void Insert(int v,int l) {
        rt[++cnt] = ++Ncnt;
        int *y = &rt[cnt],x = rt[cnt - 1];
        tr[*y] = tr[x];
        for(int i = 31 ; i >= 31 - l + 1 ; i--) {
            int c = (v >> i) & 1;
            y = &tr[*y].son[c];x = tr[x].son[c];
            *y = ++Ncnt;
            tr[*y] = tr[x];
            tr[*y].siz++;
        }
        if(!tr[*y].ed) tr[*y].ed = cnt;
    }
    int Get_MaxL(int a,int v) {
        int p = rt[a];
        int res = 0;
        for(int i = 31 ; i >= 0 ; --i) {
            int c = (v >> i) & 1;
            if(tr[p].son[c]) p = tr[p].son[c];
            else break;
            if(tr[p].ed) res = max(res,31 - i + 1);
        }
        return res;
    }
    int Query(int L,int R,int v,int len) {
        top = 0;
        --L;
        int x = rt[L],y = rt[R];
        for(int i = 31 ; i >= 0 ; --i) {
            int c = (v >> i) & 1;
            if(tr[tr[y].son[c]].siz - tr[tr[x].son[c]].siz) {
                y = tr[y].son[c];x = tr[x].son[c];
            }
            else break;
            if(tr[y].ed && 31 - i + 1 > len) {
                while(top && sta[top] > tr[y].ed) --top;
                sta[++top] = tr[y].ed;
            }
        }
        return top;
    }
    void Solve() {
        read(M);
        int a,b;
        while(M--) {
            scanf("%s",s + 1);
            if(s[1] == 'A') {
                scanf("%s",s + 1);
                int L = strlen(s + 1);
                int v = 0,now = 0;
                for(int i = 1 ; i <= L ; ++i) {
                    if(s[i] == '.' || s[i] == '/') {
                        v = v << 8 | now;
                        now = 0;
                    }
                    else now = now * 10 + s[i] - '0';
                }
                Insert(v,now);
            }
            else {
                scanf("%s",s + 1);
                int L = strlen(s + 1);
                int v = 0,now = 0;
                for(int i = 1 ; i <= L ; ++i) {
                    if(s[i] == '.') {
                        v = v << 8 | now;
                        now = 0;
                    }
                    else now = now * 10 + s[i] - '0';
                }
                v = v << 8 | now;
                read(a);read(b);
                L = Get_MaxL(a - 1,v);
                out(Query(a,b,v,L));enter;
            }
        }
    }
    int main() {
    #ifdef ivorysi
        freopen("f1.in","r",stdin);
    #endif
        Solve();
        return 0;
    }
    
  • 相关阅读:
    linq in 查询
    sql数据分组取第一条
    获取mac地址
    计算机网络体系结构分层 (OSI TCP/IP)
    2048游戏代码
    go——变量、类型、常量、函数
    关于装饰器 开放封闭
    linux杂碎知识
    crawl——scrapy(配置文件,持久化,请求传递参数,提高爬虫效率,爬虫中间件,集成selenium,去重规则)
    crawl——xpath使用
  • 原文地址:https://www.cnblogs.com/ivorysi/p/9496576.html
Copyright © 2020-2023  润新知