• DTOJ #3194. 去月球


    【题目描述】

    $Scape$ 和 $Mythological$ 交流了玩几何冲刺的经验之后,$Mythological$ 非常高兴,又推荐给 $Scape$ 一款游戏 $To the moon$。

    游戏中一位老人 $John$ 的记忆被药物尘封,进行了解除尘封的仪式之后,$Scape$ 走入了他的记忆。

    $John$ 的记忆中有一个唤做 $River$ 女孩的身影,有着数不尽的纸兔子,有一个沙包,一只鸭嘴兽玩偶,一座灯塔。$Scape$ 被深深的打动了。

    ”我的鸭嘴兽和沙包又在哪里呢?” $Scape$ 这样想到,不禁幻想出 $Mythological$ 决定给他送 $n$ 份礼物,其中第 $i$ 份的种类是 $a_i$。这些礼物按顺序排成一行。

    她挑选礼物的方式很特别,她每次会选择两份种类相同的礼物,并且这对礼物满足它们之间没有尚未拿走的礼物,并将这对礼物拿走。

    现在Scape给出了若干次询问,每次询问如果他送给她的是区间 $[L_i,R_i]$ 之间的礼物,那么她最多能拿走多少份礼物,询问强制在线。

    【输入格式】

    第 $1$ 行,三个整数 $n,m,q$ 分别是这组测试数据的大小,$a_i$ 的最大可能值,询问个数。

    第 $2$ 行, $n$ 个整数,第 $i$ 个整数表示 $a_i$。

    接下来 $q$ 行,每行两个整数 $L_i,R_i$,设 $las$ 为上一个询问的答案(初始为 $0$), 则询问的区间为 $[L_i ^ land las,R_i^ land las]$(保证合法)。

    【输出格式】

    共 $q$ 行,表示每个询问的答案。

    【样例】

    样例输入 
    样例输入1
    9 10 3
    1 1 3 2 1 1 2 3 1
    2 9
    1 2
    2 5
    样例输入2
    10 10 3
    1 2 3 4 5 6 7 8 9 10
    1 9
    2 3
    4 5 

    样例输出 
    样例输出1
    8
    2
    0
    样例输出2
    0
    0
    0

    【数据范围与提示】

    对于 $20\%$ 的数据,$1leq n leq 10^3,1leq qleq 10^3$。

    对于 $80\%$ 的数据,$1leq n leq 10^5,1leq qleq 10^5$。

    对于 $100\%$ 的数据,$1leq n leq 10^5,1leq m leq 10^5,1leq qleq 2 imes 10^6$。

    【题解】

    首先有一个性质,从左往右能删掉的区间就直接删。不难证明这一定是最优的。

    于是就可以对于每个询问从左往右扫一遍,用个栈维护即可。效率 $O(n^2)$。

    考虑优化。我们发现,对于一段区间的起点,这个起点一定属于某一个可删除块,而这个起点向后的一部分和向前的一部分应该是相同的。这样向后的一段弹栈的过程就可以理解为在前面一段的压栈过程。

    所以一个区间的可删除的点个数就相当于压栈的次数的两倍。压栈次数不好算,我们考虑不删除的部分。我们把栈用一棵 $Trie$ 树维护,用 $map$ 维护每个节点的儿子。

    从根节点出发,如果新加入的节点与当前节点颜色相同,执行弹栈操作,跳回父亲节点。如果颜色不同,就沿着该颜色边往下跳。这样每一段可删除的都已经被压缩到一个点里了。

    在这棵 $Trie$ 上,每次询问的 $l-1$ 和 $r$ 对应的节点间的距离就是无法删除的部分。往上跳的部分就是对称的部分,而往下跳的部分就刚好是后面多的部分。

    由于只求两点间距离,用 $RMQ$ 维护即可。

    【代码】

    #include<bits/stdc++.h>
    namespace IO
    {
        char C[1 << 25], D[1 << 25], *S = C;
        int T = 0;
        inline void init (void) { fread (C, 1, 1 << 25, stdin); }
        inline int read (void)
        {
            int x = 0; char c;
            do c = *S++; while ( c < '0' or c > '9' );
            do x = ( x << 1 ) + ( x << 3 ) + c - '0', c = *S++; while ( c >= '0' and c <= '9' );
            return x;
        }
        inline void write (int x)
        {
            if ( !x ) { D[T++] = '0'; D[T++] = '
    '; return; }
            char st[30]; int tp = 0;
            while ( x ) st[++tp] = x % 10 + 48, x /= 10;
            while ( tp ) D[T++] = st[tp--];
            D[T++] = '
    ';
        }
        inline void flush (void) { fwrite (D, 1, T, stdout); }
    }
    const int maxn=200000+10;
    int st[maxn][19],fst[maxn],fa[maxn],tot,dep[maxn],Log[maxn],a[maxn],n,m,q,A[maxn];
    std::unordered_map<int,int> ch[maxn];
    using namespace IO;
    std::vector<int> E[maxn];
    inline void dfs ( int u )
    {
        st[fst[u]=++tot][0]=dep[u];
        for ( int v:E[u] ) dfs(v),st[++tot][0]=dep[u];
    }
    inline int lca ( int u,int v )
    {
        int ql=fst[u],qr=fst[v];
        if ( ql>qr ) std::swap(ql,qr);
        int k=Log[qr-ql+1];
        return std::min(st[ql][k],st[qr-(1<<k)+1][k]);
    }
    signed main()
    {
        init();n=read();m=read();q=read();
        int u=0;
        for ( int i=1;i<=n;i++ )
        {
            a[i]=read()+1;
            if ( a[i]==a[u] ) u=fa[u];
            else
            {
                if ( !ch[u].count(a[i]) ) ch[u][a[i]]=i,E[u].push_back(i),fa[i]=u,dep[i]=dep[u]+1;
                u=ch[u][a[i]];
            }
            A[i]=u;
        }
        dfs(0);
        for ( int i=2;i<=tot;i++ ) Log[i]=Log[i>>1]+1;
        for ( int j=1;j<=Log[tot];j++ ) for ( int i=1;i+(1<<j)-1<=tot;i++ ) st[i][j]=std::min(st[i][j-1],st[i+(1<<(j-1))][j-1]);
        for ( int ans=0,l,r;q--; ) l=read()^ans,r=read()^ans,write(ans=r-l+1-dep[A[l-1]]-dep[A[r]]+2*lca(A[l-1],A[r]));
        flush();
        return 0;
    }
  • 相关阅读:
    Silverlight生命周期概述
    NVolecity 处理DataTable 小记
    Adobe CS6 安装的时候,安装到AdobeHelp 死掉的解决方法
    验证视图状态 MAC 失败。如果此应用程序由网络场或群集承载,请确保 配置指定了相同的 validationKey 和验证算法。不能在群集中使用 AutoGenerate 的解决办法
    为什么要写博客
    [原创]SQL发音考证(搜寻SQL86标准)
    [转载]《暗时间》:为什么你应该(从现在开始就)写博客
    [转载]《暗时间》:书写是为了更好的思考
    [原创]手把手教你写网络爬虫(1):网易云音乐歌单
    javascript简单的日历实现《转》
  • 原文地址:https://www.cnblogs.com/RenSheYu/p/11329969.html
Copyright © 2020-2023  润新知