zoukankan      html  css  js  c++  java
  • 可持久化Trie

    例题:luoguP4735

    可持久化(Trie)嘛,就和可持久化线段树差不多。这篇文章只是借例题讲一讲如何截取一段时间的信息。

    直接讲题大家就可理解。

    题目大意

    有两种操作,第一种在数组末尾加上一个数,第二种在(lleqslant pleqslant r)中求最大的$ a[p] igoplus a[ p + 1 ] igoplus ...igoplus a[ N ] igoplus x$。

    问题分析

    我们先求一个异或前缀和,记为(A)。那么第二问就变成了求在(l-1 leqslant p leqslant r-1)中最大的(A[p]igoplus A[N]igoplus x)

    然后麻烦之处就是在(p)的范围限制了。

    右端点限制非常方便,左端点的限制可以这样解决:

    我们记录一个数组(Cnt)(Cnt_i)表示(Trie)中节点(i)被多少个数经过。那么我们只要判断(Cnt_{Right}-Cnt_{Left})就可以知道在这个范围内是否可行。

    解释得不是很清楚,大家根据程序理解一下吧。

    参考程序

    // luogu-judger-enable-o2
    #include <bits/stdc++.h>
    #define LL long long
    using namespace std;
    
    const int MaxBit = 24;
    const int MaxN = 600010;
    int N, M, A[ MaxN ];
    int Trie[ MaxBit * MaxN ][ 2 ], Cnt[ MaxBit * MaxN ], Used, Root[ MaxN ];
    char Ch[ 10 ];
    
    inline void Add( int Index, int History, int Bit, int Value );
    inline int Query( int Left, int Right, int Bit, int Value );
    
    int main() {
        scanf( "%d%d", &N, &M );
        Root[ 0 ] = ++Used;
        Add( Root[ 0 ], 0, MaxBit, 0 );
        int i;
        for( i = 1; i <= N; ++i ) 
            scanf( "%d", &A[ i ] );
        for( i = 1; i <= N; ++i ) 
            A[ i ] = A[ i - 1 ] ^ A[ i ];
        for( i = 1; i <= N; ++i ) {
            Root[ i ] = ++Used;
            Add( Root[ i ], Root[ i - 1 ], MaxBit, A[ i ] );
        }
        for( i = 1; i <= M; ++i ) {
            scanf( "%s", Ch );
            if( Ch[ 0 ] == 'A' ) {
                scanf( "%d", &A[ ++N ] );
                A[ N ] = A[ N - 1 ] ^ A[ N ];
                Root[ N ] = ++Used;
                Add( Root[ N ], Root[ N - 1 ], MaxBit, A[ N ] );
            }
            if( Ch[ 0 ] == 'Q' ) {
                int l, r, x;
                scanf( "%d%d%d", &l, &r, &x );
                x ^= A[ N ];
                --l; --r;
                if( l == 0 ) 
                    printf( "%d
    ", Query( 0, Root[ r ], MaxBit, x ) );
                else 
                    printf( "%d
    ", Query( Root[ l - 1 ], Root[ r ], MaxBit, x ) );
            }
        }
        return 0;
    }
    
    
    inline void Add( int Index, int History, int Bit, int Value ) {
        if( Bit < 0 ) return;
        int T = ( Value >> Bit ) & 1;
        Trie[ Index ][ !T ] = Trie[ History ][ !T ];
        Trie[ Index ][ T ] = ++Used;
        Cnt[ Trie[ Index ][ T ] ] = Cnt[ Trie[ History ][ T ] ] + 1;
        Add( Trie[ Index ][ T ], Trie[ History ][ T ], Bit - 1, Value );
        return;
    }
    
    inline int Query( int Left, int Right, int Bit, int Value ) {
        if( Bit < 0 ) return 0;
        int T = ( Value >> Bit ) & 1;
        if( Cnt[ Trie[ Right ][ !T ] ] - Cnt[ Trie[ Left ][ !T ] ] > 0 ) 
            return ( 1 << Bit ) + Query( Trie[ Left ][ !T ], Trie[ Right ][ !T ], Bit - 1, Value );
        else 
            return Query( Trie[ Left ][ T ], Trie[ Right ][ T ], Bit - 1, Value );
    }
    
    
  • 相关阅读:
    Single Image Dehazing via Conditional Generative Adversarial Network(CVPR2018-图像去雾)
    STF-GAN:Recovering Realistic Texture in Image Super-resolution by Deep Spatial Feature Transform (CVPR2018)
    os 模块
    Pytorch-get ready with me
    Python学习(第七章)
    Python学习(第六章)
    pytorch与opencv 安装(Linux)
    Python学习(第五章)
    Python学习(第四章)
    Python学习(第三章)
  • 原文地址:https://www.cnblogs.com/chy-2003/p/10198782.html
Copyright © 2011-2022 走看看