Tree HDU4757

来源:互联网 发布:小米4c怎么设置4g网络 编辑:程序博客网 时间:2024/06/05 15:35

http://acm.hdu.edu.cn/showproblem.php?pid=4757

函数式trie,和cot差不多,用父节点递推建立子节点,此题学到了一个函数式的小技巧,就是一开始(即root[0])并不需要把所有的节点都建出来,只要让root[0]所有的后继都指向自己就可以了。

#include <iostream>#include <cstdio>#include <cstdlib>#include <cmath>#include <queue>#include <algorithm>#include <vector>#include <cstring>#include <stack>#include <cctype>#include <utility>   #include <map>#include <string>  #include <climits> #include <set>#include <string>    #include <sstream>#include <utility>   #include <ctime>#include <bitset>#pragma comment(linker, "/STACK:102400000,102400000")using std::priority_queue;using std::vector;using std::swap;using std::stack;using std::sort;using std::max;using std::min;using std::pair;using std::map;using std::string;using std::cin;using std::cout;using std::set;using std::queue;using std::string;using std::stringstream;using std::make_pair;using std::getline;using std::greater;using std::endl;using std::multimap;using std::deque;using std::unique;using std::lower_bound;using std::random_shuffle;using std::bitset;using std::upper_bound;using std::multiset;typedef long long LL;typedef unsigned long long ULL;typedef unsigned UN;typedef pair<int, int> PAIR;typedef multimap<int, int> MMAP;typedef LL TY;typedef long double LF;const int MAXN(4000010);const int MAXM(50010);const int MAXE(150010);const int MAXK(6);const int HSIZE(13131);const int SIGMA_SIZE(4);const int MAXH(20);const int INFI((INT_MAX-1) >> 1);const ULL BASE(31);const LL LIM(1e13);const int INV(-10000);const int MOD(31313);const double EPS(1e-7);const LF PI(acos(-1.0));template<typename T> inline void checkmax(T &a, T b){if(b > a) a = b;}template<typename T> inline void checkmin(T &a, T b){if(b < a) a = b;}template<typename T> inline T ABS(const T &a){return a < 0? -a: a;}struct EDGE{int v, next;} edge[200010];int first[100010], rear;void init(int n){rear = 0;memset(first, -1, sizeof(first[0])*(n+1));}void insert(int u, int v){edge[rear].v = v;edge[rear].next = first[u];first[u] = rear++;}struct LCA{int dep[200010], E[200010], pos[100010], fa[100010], table[19][200010];int back;inline int cmp(int a, int b){ return dep[a] < dep[b]? a: b;}void dfs(int u, int d, int f){fa[u] = f;E[++back] = u;dep[back] = d;pos[u] = back;for(int i = first[u]; ~i; i = edge[i].next)if(edge[i].v != f){dfs(edge[i].v, d+1, u);E[++back] = u;dep[back] = d;}}void init(){back = 0;dfs(1, 0, 0);for(int i = 1; i <= back; ++i) table[0][i] = i;for(int i = 1; (1 << i) <= back; ++i)for(int j = 1; j+(1 << i)-1 <= back; ++j)table[i][j] = cmp(table[i-1][j], table[i-1][j+(1 << (i-1))]);}int query(int a, int b){a = pos[a];b = pos[b];if(a > b) swap(a, b);int len = b-a+1, temp = 0;while((1 << temp) <= len) ++temp;--temp;return E[cmp(table[temp][a], table[temp][b-(1 << temp)+1])];}} lca;struct NODE{int sum;NODE *ch[2];} pool[MAXN], *root[100010];int back;NODE *newnode(){pool[back].ch[0] = pool[back].ch[1] = 0;pool[back].sum = 0;return pool+back++;}void updata(int dep, int val, NODE *prt, NODE *&rt){rt = pool+back++;*rt = *prt;++rt->sum;if(dep == -1) return;int id = (val >> dep)&1;updata(dep-1, val, prt->ch[id], rt->ch[id]);}int query(int val, NODE *ffrt, NODE *frt, NODE *lrt, NODE *rrt){int temp = 0;for(int i = 15; i >= 0; --i){int id = (val >> i)&1;int sm = lrt->ch[id^1]->sum+ rrt->ch[id^1]->sum- frt->ch[id^1]->sum- ffrt->ch[id^1]->sum;if(sm) id^= 1;temp = (temp << 1)|id;lrt = lrt->ch[id];rrt = rrt->ch[id];frt = frt->ch[id];ffrt = ffrt->ch[id];}return temp^val;}int arr[100010];void dfs(int u, int f){updata(15, arr[u], root[f], root[u]);for(int i = first[u]; ~i; i = edge[i].next)if(edge[i].v != f)dfs(edge[i].v, u);}int main(){int n, m;while(~scanf("%d%d", &n, &m)){back = 0;root[0] = newnode();root[0]->ch[0] = root[0]->ch[1] = root[0];for(int i = 1; i <= n; ++i) scanf("%d", arr+i);int u, v;init(n);for(int i = 1; i < n; ++i){scanf("%d%d", &u, &v);insert(u, v);insert(v, u);}lca.init();dfs(1, 0);int val;for(int i = 0; i < m; ++i){scanf("%d%d%d", &u, &v, &val);printf("%d\n", query(val, root[lca.fa[lca.query(u, v)]], root[lca.query(u, v)], root[u], root[v]));}}return 0;}



原创粉丝点击