P3292 [SCOI2016]ラッキー数
タイトル説明
国n個の都市があり、これらの都市は、n-1道路、任意の二つの都市が相互に到達できるように、唯一の経路で接続されています。すべての都市は、市のシンボルとして、市の中心部にあるモニュメントスタンドの形で、ラッキーナンバーを持っています。
いくつかの旅行者が国を探索したいです。ボイジャー面がX-Y番号沿いの都市間、都市のx個で市内観光パスの唯一の作品を上陸させ、最終的には国にYを残して街から離陸しました。すべての都市を通過する間、誰が街のラッキーナンバーを訪問し、撮影する機会がありますので、これは自分自身を救うために幸運になります。しかし、幸いなことに、単純に重畳されていない、このツアーはまた、非常に明確でした。彼らはラッキーナンバーは別の方法で崇拝するか、彼の体に残ります。
例えば、3枚の写真を撮ったツアーは、幸いにも値が5,7,11であり、最終的な自分自身を保持する幸運値は9(5 XOR 7 XOR 11)です。
いくつかの巧妙なツアーは限り選択的に多くの幸運値を得ることができるようになり、写真を撮るために、発見されました。幸いなことに、値が上記例では3は、わずか5および11を選択し、値14はラッキー保持することができます。さて、気の利いたいくつかのツアーでは、あなたは、私はあなたが彼らの旅程で幸運の最大値は保持することができ計算に役立ちたいと考えています。
入力形式
最初の行は、2つの正の整数nは、Qが含まれており、旅行者の数は、都市の数を表します。
2行目は、Giはi番目の整数値都市のIラッキー数を表す非負整数nを含んでいます。
次いで、N-1行、2つの正の整数xを含む各行は、Y、XおよびY番号都市間の都市の道路の数に結合された表現しました。
そして、Qライン、各ラインは、2つの正の整数X、Yが含まれている旅行者の旅程の名前は、都市部のY数番号にxからであることを示します。N <= 20000、Q <= 200000、Giの<= 2 ^ 60
出力フォーマット
Q出力は、各行が保つことができる幸運な旅行者の名前の最大値を表す非負整数を含む行を含める必要があります。
サンプル入力と出力
4 2 11 5 7 9 1 2 1 3 1 4 2 3 1 4
14 11
解決策:パス上の要件XOR最大値、我々はその後、どのように我々は2つの都市間の線形ベースで行うのですか、需要の最大XOR値がリニアベースで行うことができることをご存知ですか?私たちは、n個の都市や道路がツリーを構成することが、我々はLCAは、その2つのリニアLCAに基づくLCAには2つの都市がこのパスに乗るために組み合わせるこれら二つの都市を見つけることができます知っています。通常、DIS記録リニアアレイグループのメンテナンスに使用される配列を掛けます。
コード:
#include <ビット/ STDC ++ H> の#defineは長い長いllの 使用 名前空間STDを、 CONSTの INT N = 2E4 + 10 。 LL [N]、B [N] [ 20 ] [ 70 ]、DEP [N]、ANS [ 70 ]、FA [N] [ 20 ]。 ベクター < INT > V [N]。 LL読み出す(){ LL、X = 0、F = 1 。 チャー CH = GETCHAR()。 一方、(CH> ' 9 ' || CH < ' 0 ' ){ もし(CH == ' - ')、F = - 1 。 CH = GETCHAR()。 } 一方、(CH> = ' 0 ' && CH <= ' 9 ' ){ X = X * 10 + CH- ' 0 ' 。 CH = GETCHAR()。 } 戻りのx *のF。 } ボイド追加(LLのB []、LLのX){ ため(int型私= 63 ; I> = 0 ; i-- ){ もし(X&(1LL << I)){ 場合(B [i])とX ^ = B [i]は、 他{ B [i]は =のX。 破ります; } } } } ボイドマージ(LL B1は[]、LL B2は、[]){ ため(int型私= 63 ; I> = 0 ; i-- ) 場合(B2 [I])を追加し(B1、B2 [i])と; } ボイド DFS(INT F、int型U)を{ FA [U] [ 0 ] = Fと、 DEP [U]= DEP [F] + 1 。 以下のために(int型 i = 1 ; iは<= 15 ; iは++ ){ FA [U] [I] = FA [FA [U] [I- 1 ]] [I- 1 ]。 マージ(B [U] [I]、B [U] [I - 1 ])。 マージ(B [U] [I]、B [FA [U] [I - 1 ] [I- 1 ])。 } のために(int型 i = 0 ; iはV <[U] .size(); iは++ ){ 場合(==のV F [U] [i])と続けます。 DFS(U、V [U] [I])。 } } のボイドLCA(int型のx、int型のY){ memsetの(ANS、0、はsizeof (ANS))。 もし(DEP [X] < DEP [Y])スワップ(X、Y) 以下のために(int型 = Iを15 ; I> = 0 ; i-- ) 場合(DEP [FA [X] [I]]> = DEP [Y]){ マージ(ANS B [X] [I])。 X = FA [X] [I]; } 場合(x == y)は{ マージ(ANS、B [X] [ 0 ])。 返します。 } のための(INT私は= 15 ; I> = 0 ; i-- ) 場合(FA [X] [I] =!FA [Y] [I]){ (マージANS、B [X] [I])。 マージ(ANS、B [Y] [I])。 X = FA [X] [I]; Y = FA [Y] [I]。 } マージ(ANS、B [X] [ 0 ])。 マージ(ANS、B [Y] [ 0 ])。 マージ(ANS、B [FA [X] [ 0 ] [ 0 ])。 } int型のmain(){ LL N =読み取る()、Q = 読み取り()、X、Y。 用 LL I =(1 iは<= N; I ++) 追加(B [i]が[ 0 ]、[I] = 読み取ります())。 以下のために(LL i = 1 ; iがn <; Iは++ ){ Xの =(読み取り)、Yは= )(読み取ります。 V [X] .push_back(Y)。 V [Y] .push_back(X)。 } DFS(0、1 )。 ながら(q-- ){ X =リード()、yは。= 読み取ります(); LCA(X、Y) LL合計 = 0 ; 以下のために(int型私は= 63 ; I> = 0 ; i-- ) の合計マックス=(SUM、SUM ^ ANS [I]); のprintf(" %のLLDの\のN- " 、SUM); } の戻り 0 ; } // 変数が間違って一時間以上のバグを見つけるために探して