zoukankan      html  css  js  c++  java
  • [SCOI2016]幸运数字

    [SCOI2016]幸运数字

    这其实就是把线性基搬到了树上,其实很简单.

    因为线性基显然可以合并,所以直接用线段树维护即可.

    套一个树剖,维护这棵维护线性基的线段树就好了.

    问题只有一个字 (:)(!)

    #pragma GCC optimize(2)
    #pragma GCC optimize(3)
    #pragma GCC target("sse,sse2,sse3,sse4.1,sse4.2,popcnt,abm,mmx,avx")
    #pragma comment(linker,"/STACK:102400000,102400000")
    #pragma GCC optimize("Ofast")
    #pragma GCC optimize("inline")
    #pragma GCC optimize("-fgcse")
    #pragma GCC optimize("-fgcse-lm")
    #pragma GCC optimize("-fipa-sra")
    #pragma GCC optimize("-ftree-pre")
    #pragma GCC optimize("-ftree-vrp")
    #pragma GCC optimize("-fpeephole2")
    #pragma GCC optimize("-ffast-math")
    #pragma GCC optimize("-fsched-spec")
    #pragma GCC optimize("unroll-loops")
    #pragma GCC optimize("-falign-jumps")
    #pragma GCC optimize("-falign-loops")
    #pragma GCC optimize("-falign-labels")
    #pragma GCC optimize("-fdevirtualize")
    #pragma GCC optimize("-fcaller-saves")
    #pragma GCC optimize("-fcrossjumping")
    #pragma GCC optimize("-fthread-jumps")
    #pragma GCC optimize("-funroll-loops")
    #pragma GCC optimize("-fwhole-program")
    #pragma GCC optimize("-freorder-blocks")
    #pragma GCC optimize("-fschedule-insns")
    #pragma GCC optimize("inline-functions")
    #pragma GCC optimize("-ftree-tail-merge")
    #pragma GCC optimize("-fschedule-insns2")
    #pragma GCC optimize("-fstrict-aliasing")
    #pragma GCC optimize("-fstrict-overflow")
    #pragma GCC optimize("-falign-functions")
    #pragma GCC optimize("-fcse-skip-blocks")
    #pragma GCC optimize("-fcse-follow-jumps")
    #pragma GCC optimize("-fsched-interblock")
    #pragma GCC optimize("-fpartial-inlining")
    #pragma GCC optimize("no-stack-protector")
    #pragma GCC optimize("-freorder-functions")
    #pragma GCC optimize("-findirect-inlining")
    #pragma GCC optimize("-fhoist-adjacent-loads")
    #pragma GCC optimize("-frerun-cse-after-loop")
    #pragma GCC optimize("inline-small-functions")
    #pragma GCC optimize("-finline-small-functions")
    #pragma GCC optimize("-ftree-switch-conversion")
    #pragma GCC optimize("-foptimize-sibling-calls")
    #pragma GCC optimize("-fexpensive-optimizations")
    #pragma GCC optimize("-funsafe-loop-optimizations")
    #pragma GCC optimize("inline-functions-called-once")
    #pragma GCC optimize("-fdelete-null-pointer-checks")
    #include <algorithm>
    #include <iostream>
    #include <cstdlib>
    #include <cstring>
    #include <cstdio>
    #include <string>
    #include <vector>
    #include <queue>
    #include <cmath>
    #include <ctime>
    #include <map>
    #include <set>
    #define MEM(x,y) memset ( x , y , sizeof ( x ) )
    #define rep(i,a,b) for (int i = (a) ; i <= (b) ; ++ i)
    #define per(i,a,b) for (int i = (a) ; i >= (b) ; -- i)
    #define pii pair < int , int >
    #define one first
    #define two second
    #define rint read<int>
    #define rll read<LL>
    #define LL long long
    #define pb push_back
    #define db double
    #define ull unsigned long long
    #define lowbit(x) ( x & ( - x ) )
    
    using std::queue ;
    using std::set ;
    using std::pair ;
    using std::max ;
    using std::min ;
    using std::priority_queue ;
    using std::vector ;
    using std::swap ;
    using std::sort ;
    using std::unique ;
    using std::greater ;
    
    template < class T >
        inline T read () {
            T x = 0 , f = 1 ; char ch = getchar () ;
            while ( ch < '0' || ch > '9' ) {
                if ( ch == '-' ) f = - 1 ;
                ch = getchar () ;
            }
           while ( ch >= '0' && ch <= '9' ) {
                x = ( x << 3 ) + ( x << 1 ) + ( ch - 48 ) ;
                ch = getchar () ;
           }
           return f * x ;
        }
    
    const int BITs = 65 ;
    const int N = 2e4 + 100 ;
    
    class LinearBasis {
        public : LL base[BITs] ;
        public :
            inline void clear () { MEM ( base , 0ll ) ; return ; }
        public :
            inline void insert (LL x) {
                if ( ! x ) return ;
                for (int i = 62 ; ~ i ; -- i)
                    if ( x & ( 1ll << i ) ) {
                        if ( base[i] ) x ^= base[i] ;
                        else { base[i] = x ; return ; }
                    }
                return ;
            }
        public :
            inline LL query () {
                LL res = 0ll ;
                for (int i = 62 ; ~ i ; -- i)
                    res = max ( res , res ^ base[i] ) ;
                return res ;
            }
    } ;
    
    struct edge { int to , next ; } e[N<<1] ;
    
    int tot , head[N] ;
    int n , q , f[N] , deep[N] , siz[N] ;
    int son[N] , idx[N] , ind , top[N] ;
    LL v[N] , val[N] ;
    
    inline LinearBasis merge (LinearBasis a , LinearBasis b) {
        LinearBasis res = a ;
        for (int i = 62 ; ~ i ; -- i) if ( b.base[i] ) res.insert ( b.base[i] ) ;
        return res ;
    }
    
    class segment {
    
        #define mid ( ( l + r ) >> 1ll )
    
        private : struct seg { int ls , rs ; LinearBasis data ; } t[N<<1] ;
    
        private : int cnt ;
    
        public : inline void clear () { cnt = 1ll ; return ; }
    
        public :
            inline void pushup (int rt) { t[rt].data = merge ( t[t[rt].ls].data , t[t[rt].rs].data ) ; return ; }
    
        public :
            inline void build (int rt , int l , int r) {
                if ( l == r ) { t[rt].data.clear () ; t[rt].data.insert ( v[l] ) ; return ; }
                t[rt].ls = ++ cnt ; build ( t[rt].ls , l , mid ) ;
                t[rt].rs = ++ cnt ; build ( t[rt].rs , mid + 1 , r ) ;
                pushup ( rt ) ; return ;
            }
    
        public :
            inline LinearBasis query (int rt , int l , int r , int ll , int rr) {
                if ( ll == l && r == rr ) return t[rt].data ;
                if ( rr <= mid ) return query ( t[rt].ls , l , mid , ll , rr ) ;
                else if ( ll > mid ) return query ( t[rt].rs , mid + 1 , r , ll , rr ) ;
                else return merge ( query ( t[rt].ls , l , mid , ll , mid ) , query ( t[rt].rs , mid + 1 , r , mid + 1 , rr ) ) ;
            }
    
        #undef mid
    
    } T ;
    
    inline void build (int u , int v) { e[++tot].next = head[u] ; e[tot].to = v ; head[u] = tot ; return ; }
    
    inline void dfs (int cur , int anc , int dep) {
        f[cur] = anc ; deep[cur] = dep ; siz[cur] = 1 ;
        int maxson = - 1 ;
        for (int i = head[cur] ; i ; i = e[i].next){
            int k = e[i].to ; if ( k == anc ) continue ;
            dfs ( k , cur , dep + 1 ) ; siz[cur] += siz[k] ;
            if ( siz[k] > maxson ) maxson = siz[k] , son[cur] = k ;
        }
        return ;
    }
    
    inline void _dfs (int cur , int topf) {
        top[cur] = topf ; idx[cur] = ++ ind ; v[ind] = val[cur] ;
        if ( ! son[cur] ) return ; _dfs ( son[cur] , topf ) ;
        for (int i = head[cur] ; i ; i = e[i].next){
            int k = e[i].to ;
            if ( k == f[cur] || k == son[cur] ) continue ;
            _dfs ( k , k ) ;
        }
        return ;
    }
    
    inline LL qrange (int x , int y) {
        LinearBasis res ; res.clear () ;
        while ( top[x] != top[y] ) {
            if ( deep[top[x]] < deep[top[y]] ) swap ( x , y ) ;
            res = merge ( res , T.query ( 1 , 1 , ind , idx[top[x]] , idx[x] ) ) ;
            x = f[top[x]] ;
        }
        if ( deep[x] > deep[y] ) swap ( x , y ) ;
        res = merge ( res , T.query ( 1 , 1 , ind , idx[x] , idx[y] ) ) ;
        return res.query () ;
    }
    
    int main () {
        n = rint () ; q = rint () ;
        rep ( i , 1 , n ) val[i] = rll () ;
        rep ( i , 2 , n ) {
            int x = rint () , y = rint () ;
            build ( x , y ) ; build ( y , x ) ;
        }
        dfs ( 1 , 0 , 1 ) ; _dfs ( 1 , 1 ) ;
        T.clear () ; T.build ( 1 , 1 , ind ) ;
        while ( q -- ) {
            int x = rint () , y = rint () ;
            printf ("%lld
    " , qrange ( x , y ) ) ;
        }
        return 0 ;
    }
    

    这种写法可能会很慢,因为它是三个 (log) 的.

    所以需要卡卡常.

    问题不大.

    还可以用倍增去做,能消掉一个 (log).

    具体实现就不说了,应该很简单.

  • 相关阅读:
    hdu 1106 排序(排序)
    hdu 1040 As Easy As A+B(排序)
    hdu 1029 Ignatius and the Princess IV(排序)
    mysql-9索引
    mysql-8 alter命令
    mysql-7事务管理
    mysql-6正则表达式
    http协议
    9-2交互体验
    9-2专项测试下午
  • 原文地址:https://www.cnblogs.com/Equinox-Flower/p/11736926.html
Copyright © 2011-2022 走看看