1. 程式人生 > >BZOJ4568 [線性基][樹鏈剖分][線段樹]

BZOJ4568 [線性基][樹鏈剖分][線段樹]

Description

A 國共有 n 座城市,這些城市由 n-1 條道路相連,使得任意兩座城市可以互達,且路徑唯一。每座城市都有一個幸運數字,以紀念碑的形式矗立在這座城市的正中心,作為城市的象徵。一些旅行者希望遊覽 A 國。旅行者計劃乘飛機降落在 x 號城市,沿著 x 號城市到 y 號城市之間那條唯一的路徑遊覽,最終從 y 城市起飛離開 A 國。在經過每一座城市時,遊覽者就會有機會與這座城市的幸運數字拍照,從而將這份幸運儲存到自己身上。然而,幸運是不能簡單疊加的,這一點遊覽者也十分清楚。他們迷信著幸運數字是以異或的方式保留在自己身上的。例如,遊覽者拍了 3 張照片,幸運值分別是 5,7,11,那麼最終保留在自己身上的幸運值就是 9(5 xor 7 xor 11)。有些聰明的遊覽者發現,只要選擇性地進行拍照,便能獲得更大的幸運值。例如在上述三個幸運值中,只選擇 5 和 11 ,可以保留的幸運值為 14 。現在,一些遊覽者找到了聰明的你,希望你幫他們計算出在他們的行程安排中可以保留的最大幸運值是多少。

Solution

看到求異或最大值,是可以用線性基的,想到線性基是可以合併的,就可以用樹鏈剖分加線段樹維護。

#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;

const int N = 20202;
typedef long long ll;

inline char get(void) {
  static char buf[100000], *S = buf, *T = buf;
  if (S == T) {
    T = (S = buf) + fread(buf, 1
, 100000, stdin); if (S == T) return EOF; } return *S++; } template<typename T> inline void read(T &x) { static char c; x = 0; for (c = get(); c < '0' || c > '9'; c = get()); for (; c >= '0' && c <= '9'; c = get()) x = x * 10 + c - '0'; } struct LB { ll a[65]; inline
void Clear(void) { memset(a, 0, sizeof a); } inline LB(void) { Clear(); } inline ll Insert(ll x) { for (int i = 60; i >= 0; i--) if ((1ll << i) & x) { if (!a[i]) { a[i] = x; break; } x ^= a[i]; } return x; } inline ll &operator [](int x) { return a[x]; } inline ll Max(void) { ll mx = 0; for (int i = 60; i >= 0; i--) if ((mx ^ a[i]) > mx) mx ^= a[i]; return mx; } }; struct edge { int to, next; edge(int t = 0, int n = 0):to(t), next(n) {} }; edge G[N << 1]; int head[N]; ll val[N]; int fa[N], dep[N], size[N], top[N], pos[N], son[N]; int Gcnt, Pcnt, n, q, x, y, f1, f2; LB T[N << 3]; LB ans; inline void AddEdge(int from, int to) { G[++Gcnt] = edge(to, head[from]); head[from] = Gcnt; G[++Gcnt] = edge(from, head[to]); head[to] = Gcnt; } inline LB Merge(LB &a, LB &b) { LB c = a; for (int i = 60; i >= 0; i--) if (b[i]) c.Insert(b[i]); return c; } void dfs1(int u) { size[u] = 1; for (int i = head[u]; i; i = G[i].next) { if (fa[u] == G[i].to) continue; dep[G[i].to] = dep[u] + 1; fa[G[i].to] = u; dfs1(G[i].to); size[u] += size[G[i].to]; if (size[son[u]] < size[G[i].to]) son[u] = G[i].to; } } void dfs2(int u, int t) { top[u] = t; pos[u] = ++Pcnt; if (son[u]) dfs2(son[u], t); for (int i = head[u]; i; i = G[i].next) if (son[u] != G[i].to && fa[u] != G[i].to) dfs2(G[i].to, G[i].to); } void Insert(int o, int l, int r, int pos, ll v) { if (l == r) return (void)(T[o].Insert(v)); int mid = (l + r) >> 1; if (pos <= mid) Insert(o << 1, l, mid, pos, v); else Insert(o << 1 | 1, mid + 1, r, pos, v); T[o] = Merge(T[o << 1], T[o << 1 | 1]); } void Query(int o, int l, int r, int L, int R) { if (l >= L && r <= R) return (void)(ans = Merge(T[o], ans)); int mid = (l + r) >> 1; LB res; if (L <= mid) Query(o << 1, l, mid, L, R); if (R > mid) Query(o << 1 | 1, mid + 1, r, L, R); } int main(void) { read(n); read(q); for (int i = 1; i <= n; i++) read(val[i]); for (int i = 1; i < n; i++) { read(x); read(y); AddEdge(x, y); } dfs1(1); dfs2(1, 1); for (int i = 1; i <= n; i++) Insert(1, 1, n, pos[i], val[i]); while (q--) { read(x); read(y); ans.Clear(); f1 = top[x]; f2 = top[y]; while (f1 != f2) { if (dep[f1] < dep[f2]) { swap(x, y); swap(f1, f2); } Query(1, 1, n, pos[f1], pos[x]); x = fa[f1]; f1 = top[x]; } if (dep[x] > dep[y]) swap(x, y); Query(1, 1, n, pos[x], pos[y]); printf("%lld\n", ans.Max()); } return 0; }

相關推薦

BZOJ4568 [線性][][線段]

Description A 國共有 n 座城市,這些城市由 n-1 條道路相連,使得任意兩座城市可以互達,且路徑唯一。每座城市都有一個幸運數字,以紀念碑的形式矗立在這座城市的正中心,作為城市的象徵。一些旅行者希望遊覽 A 國。旅行者計劃乘飛機降落在 x 號城市

【bzoj2836】魔法 +線段

urn fin pan online char font -s class efi 題目描述 輸入 輸出 樣例輸入 4 0 1 1 2 2 3 4 Add 1 3 1 Query 0 Query 1 Query 2 樣例輸出

[bzoj 2243]: [SDOI2011]染色 [][線段]

節點 query ext tran pac led str 包含 sans Description 給定一棵有n個節點的無根樹和m個操作,操作有2類: 1、將節點a到節點b路徑上所有點都染成顏色c; 2、詢問節點a到節點b路徑上的顏色段數量(連續相同顏色被認為是同

BZOJ2243 [SDOI2011]染色(+線段合並)

ech sca 註意 get printf truct bre sum lca 題目鏈接 BZOJ2243 樹鏈剖分+線段樹合並 線段樹合並的一些細節需要註意一下 #include <bits/stdc++.h> using namespace std;

【BZOJ1969】[Ahoi2005]LANE 航線規劃 離線++線段

個數 wap 鎖定 樹邊 mes zoj swap 相同 swa 【BZOJ1969】[Ahoi2005]LANE 航線規劃 Description 對Samuel星球的探險已經取得了非常巨大的成就,於是科學家們將目光投向了Samuel星球所在的星系—&md

BZOJ 2157 旅遊(+線段

ace 路徑 pan geo blog return amp min target 【題目鏈接】 http://www.lydsy.com/JudgeOnline/problem.php?id=2157 【題目大意】   支持修改邊,鏈上查詢最大值最小值總和

hdu3966 +線段 裸題

ont ret algo string map fine eof inf 初始化 HDU - 3966 題意:給一顆樹,3種操作,Q u 查詢u節點的權值,I a b c 對a到b的路徑上每個點的點權增加c,D a b c 對a b 路徑上所有點的點權減少c 思路:樹鏈剖

【BZOJ4811】[Ynoi2017]由乃的OJ +線段

size 數值 sin 分數 strong str blank cstring else 【BZOJ4811】[Ynoi2017]由乃的OJ Description 由乃正在做她的OJ。現在她在處理OJ上的用戶排名問題。OJ上註冊了n個用戶,編號為1~",一開始他們

HDU-3966 Aragorn's Story(+線段)

real letter 們的 等等 then 需要 family sea inpu Aragorn‘s Story Time Limit: 10000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Ot

【BZOJ4127】Abs +線段

include modify 題目 etc soft upd clu set mem 【BZOJ4127】Abs Description 給定一棵樹,設計數據結構支持以下操作 1 u v d  表示將路徑 (u,v) 加d 2 u v

HDU 5893 List wants to travel(+線段

color top ons set 基本 brush [0 pri cto 題目鏈接 HDU5893 2016年ICPC沈陽網絡賽的B題。這道題其和 BZOJ2243 基本一樣 那道題我也寫了題解 點這裏 兩道題的區別就是BZOJ這題是點的權值,這道題是邊權。 所以

【bzoj2238】Mst 最小生成樹++線段

生成樹 brush 輸出 兩個 下一條 整數 algorithm ted sin 題目描述 給出一個N個點M條邊的無向帶權圖,以及Q個詢問,每次詢問在圖中刪掉一條邊後圖的最小生成樹。(各詢問間獨立,每次詢問不對之後的詢問產生影響,即被刪掉的邊在下一條詢問中依然存在) 輸

BZOJ2157: 旅遊 線段

const ostream one size con head log alt 一行 http://www.lydsy.com/JudgeOnline/problem.php?id=2157 在對樹中數據進行改動的時候需要很多pushdown(具體操作見代碼),不然會w

BZOJ 4034: [HAOI2015]樹上操作 線段

|| 線段 top www. img 復習 如果 ext hide http://www.lydsy.com/JudgeOnline/problem.php?id=4034 算是對線段樹的一個復習,樹鏈剖分+區間增減單點增減區間查詢。真的簡單到不用lca,但是線段樹又寫

【BZOJ3626】[LNOI2014]LCA 離線++線段

log 根路徑 iostream 根節點 2個 scrip har eof family 【BZOJ3626】[LNOI2014]LCA Description 給出一個n個節點的有根樹(編號為0到n-1,根節點為0)。一個點的深度定義為這個節點到根的距離+1。設d

【BZOJ4515】[Sdoi2016]遊戲 +線段

以及 hint odi 區間 char alice return clas cstring 【BZOJ4515】[Sdoi2016]遊戲 Description Alice 和 Bob 在玩一個遊戲。 遊戲在一棵有 n 個點的樹上進行。最初,每個點上都只有一個數字

【BZOJ2164】采礦 +線段維護DP

sca uil des 描述 數據 == std 單位 邊表 【BZOJ2164】采礦 Description 浩浩蕩蕩的cg大軍發現了一座礦產資源極其豐富的城市,他們打算在這座城市實施新的采礦戰略。這個城市可以看成一棵有n個節點的有根樹,我們把每個節點用1到n的整

B20J_2243_[SDOI2011]染色_+線段

線段 scanf head == 組成 樹鏈剖分 線段樹 lazy reg B20J_2243_[SDOI2011]染色_樹鏈剖分+線段樹 一下午凈調這題了,爭取晚上多做幾道。 題意: 給定一棵有n個節點的無根樹和m個操作,操作有2類: 1、將節點a到節點b路徑上所有點都

[BZOJ2402]陶陶的難題II(+線段維護凸包+分數規劃)

五行 add urn build 一行 輸入格式 for res 限制 陶陶的難題II 時間限制:40s 空間限制:128MB 題目描述 輸入格式 第一行包含一個正整數N,表示樹中結點的個數。 第二行包含N個正實數,第i個數表示xi

Aragorn's Story +線段 && +狀數組

date shu 更新 none ++ span display struct mem Aragorn‘s Story 來源:http://120.78.128.11/Problem.jsp?pid=2710 來源:http://acm.hdu.edu.cn/showpro