早就聽過用字典樹求異或最大值,然而沒做過。發現一碰到異或的題就gg,而且因為以前做過的一道類似的題(事實上並不類似)限制了思路,蠢啊= =。
題意:一棵帶權的樹,求任意兩點間路徑異或的最大值。
題解:設xor(a,b)是求a,b間路徑的異或值,那麼xor(a,b)=xor(root,a)^xor(root,b)。因為如果lca(a,b)==root時結論顯然成立,不然的話就會有重複走過的部分,但是異或有性質x^x=0,所以lca(a,b)!=root結論依然成立。
這樣題目就很簡單了。對每乙個xor(root,i)(0
#include #include#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define pk printf("lalala");
#define ppp(x) printf("%d\n", x)
using
namespace
std;
#define pi acos(-1.0)
#define exp exp(1.0)
#define eps 1e-6
#define clr(x,c) memset(x,c,sizeof(x))
const
int kind = 2
;const
int maxn = 5000005
;const
int n = 100005
;int
cnt_node;
struct
node
} heap[maxn];
node *root;
intxor[n];
inline node*new_node()
void insert(node* root, int *str)
}int count(node* root, int *str)
else
}return
ans;
}struct
edge edge[n * 2
];int
cnt_edge;
inthead[n];
void add_edge(int u, int v, int
w)void dfs(int u, int fa, int
val)
}int str[n][40
];int
main()
dfs(
0, -1, 0
);
//for (int i = 0; i < n; ++i) printf("%d ", xor[i]); printf("\n");
int ans = 0
;
for (int i = 0; i < n; ++i)
//for (int j = 0; j < idx; ++j) printf("%d ", str[i][j]); printf("\n");
insert(root, str[i]);
}for (int i = 0; i < n; ++i)
printf(
"%d\n
", ans);
}return0;
}
poj 3764 最長異或路徑 二進位制trie樹)
問題描述 給你一棵樹,n個節點,n 1條邊每條邊i都有乙個權值wi。定義任意兩點間的權值為 這兩點間的路徑上的所有邊的值的異或。比如a點和b點間有i,j,k三條邊,那麼ab兩點間的權值為 wi wj wk。求這個最大的權值 最長異或路徑 輸入格式 第一行為n表示節點數目 節點編號為1.n 接下來的n...
字典樹處理《異或》
題目 問題很簡單,現在有乙個陣列a1,a2,a3 an。你的任務就是找到乙個連續子段 l,r 使得al al 1 ar達到最大。input 多組輸入,每組有兩行。第一行有乙個整數n 1 n 10 5 表示陣列的元素個數。第二行有n個元素,依次表示陣列的元素。0 ai 10 6 output 每組輸出...
nefu1248智力異或 字典樹
problem 1248 time limit 2000ms memory limit 65535k 有乙個數列包含n個正整數a 1 a n 1 n 1e5,0 a i 1e9 現在有q次操作 q 1e5 每次操作是以下兩種操作中的一種 1 輸入x,對這n個數分別異或x 2 輸入x,求數列中的某個數...