zoukankan      html  css  js  c++  java
  • 【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;
    }
    
  • 相关阅读:
    LabelImg 图像图像标注工具
    周杰伦的2000w个故事
    ROS 订阅图像节点(1)
    ROS 订阅图像节点
    ROS 双目标定
    书籍
    Z30云台PC控制问题
    大疆M600组装和试飞
    M100 X3云台安装
    M100 组装教程
  • 原文地址:https://www.cnblogs.com/ivorysi/p/9496576.html
Copyright © 2011-2022 走看看