[T2] 2019년 8월 6일 계 시뮬레이션 게임 경로 트리 (트리) (트리는)

폭력 변환 이탈리아 것을 고려

우리가 경로의 양쪽 끝을 열거, 가장 폭력적인 접근 방식을 고려하고 두 뿌리의 기여를 계산하는 트리 방식의 유사한 경로 길이를 추구하고 제거 \ (LCA \) 두 번 뿌리를 기여할 수 있습니다.

즉 것으로 가정된다 \ (V_I \)\ (I는 \) 루트 경로와 XOR 다음에 오른쪽면 (\ (X, Y) \ ) 응답은 :

\ [v_x \ XOR \ v_y \ XOR \ {V_ LCA (X, Y)} \ XOR \ {V_ LCA (X, Y)} \]

때문에 (\ {V_ LCA를 (X, Y)} \ XOR \ {V_ LCA를 (X, Y) = 0} \) 이므로 응답은 :

\ [V_x \ XOR \ v_y \]

따라서, 질문의 의미는, 어떤 숫자, 두 숫자의 독점 또는 최대 값을 찾으된다.

\ (트리는 \) 트리

우리는 각 \ (V_I \) 에 던져 \ (트리는 \) , 다음 각 \ (V_I \) 에서 \ (트리는 \) 트리 쿼리 XOR 최대 값 (약간 운영 기본).

이게 다예요.

코드

#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define Reg register
#define RI Reg int
#define Con const
#define CI Con int&
#define I inline
#define W while
#define N 1000000
#define add(x,y,v) (e[++ee].nxt=lnk[x],e[lnk[x]=ee].to=y,e[ee].val=v)
#define Gmax(x,y) (x<(y)&&(x=(y)))
using namespace std;
int n,ee,lnk[N+5];struct edge {int to,nxt,val;}e[N<<1];
class FastIO
{
    private:
        #define FS 100000
        #define tc() (A==B&&(B=(A=FI)+fread(FI,1,FS,stdin),A==B)?EOF:*A++)
        #define tn (x<<3)+(x<<1)
        #define D isdigit(c=tc())
        char c,*A,*B,FI[FS];
    public:
        I FastIO() {A=B=FI;}
        Tp I void read(Ty& x) {x=0;W(!D);W(x=tn+(c&15),D);}
}F;
class TrieSolver
{
    private:
        int v[N+5];
        template<int SZ,int BIT> class Trie//Trie树
        {
            private:
                int rt,Nt,V[SZ*BIT+5],S[SZ*BIT+5][2];
                I void Ins(CI v,int& rt,CI d) {!rt&&(rt=++Nt),~d&&(Ins(v,S[rt][v>>d&1],d-1),0);}//插入
                I int Qry(CI v,CI rt,CI d)//求最大异或值
                {
                    if(!rt||!~d) return 0;RI t=v>>d&1;
                    return S[rt][t^1]?(Qry(v,S[rt][t^1],d-1)|(1<<d)):Qry(v,S[rt][t],d-1);//能取1就取1
                }
            public:
                I void Ins(CI v) {Ins(v,rt,BIT);}
                I int Qry(CI v) {return Qry(v,rt,BIT);}
        };Trie<N,30> T;
        I void dfs(CI x,CI lst=0)//dfs遍历
        {
            RI i;for(i=lnk[x];i;i=e[i].nxt) e[i].to^lst&&
                (v[e[i].to]=v[x]^e[i].val,dfs(e[i].to,x),0);T.Ins(v[x]);
        }
    public:
        I void Solve()
        {
            RI i,t,ans=0;for(dfs(1),i=1;i<=n;++i) t=T.Qry(v[i]),Gmax(ans,t);//枚举v求答案
            printf("%d",ans);//输出答案
        }
}S;
int main()
{
    freopen("tree.in","r",stdin),freopen("tree.out","w",stdout);
    RI i,x,y,z;for(F.read(n),i=1;i^n;++i) F.read(x),F.read(y),F.read(z),add(x,y,z),add(y,x,z);
    return S.Solve(),0;
}

추천

출처www.cnblogs.com/chenxiaoran666/p/Contest20190806T2.html