P3292 [SCOI2016] lucky number (linear multiplication yl)

Title Description

A country there are n cities, these cities are connected by n-1 road, such that any two cities can reach each other, and the only path. Every city has a lucky number, in the form of a monument stands in the center of the city, as a symbol of the city.

A few travelers wishing to explore the country. Voyager plane landed in x number of cities, between cities along the x-y No. No. The only piece of city tour path, finally took off from the city to leave the country A y. While passing through every city, who will have the opportunity to visit and photograph the lucky number of the city, so this will be lucky to save himself. Fortunately, however, is not simply superimposed, this tour had also been very clear. They adore the lucky number is a different way or remain in his body.

For example, the tour who took three photos, fortunately values ​​are 5,7,11, then the final to retain himself lucky value is 9 (5 xor 7 xor 11).

Some clever tour were found, as long as selectively to take pictures, will be able to get more lucky value. Fortunately, the value three in the above example, only select 5 and 11, the value 14 can be retained lucky. Now, some tour who found clever you, I hope you help them calculate the maximum value fortunate in their itinerary can be retained is.

Input and output formats

Input formats:

The first line contains two positive integers n, q, and the number of travelers denote the number of cities.

The second line contains a non-negative integer n, where Gi denotes the i-th integer value i lucky number of cities.

Then n-1 rows, each row comprising two positive integers x, y, expressed coupled to a number of urban road between x and y number city.

Then q lines, each line contains two positive integers x, y, indicate the name of the traveler's itinerary is from x to y number number of urban cities. N <= 20000, Q <= 200000, Gi <= 2 ^ 60

Output formats:

Q output need to include lines, each line contains a non-negative integer representing the maximum value of the name of the lucky travelers can keep.

Sample input and output

Input Sample # 1: Copy
4 2
11 5 7 9
1 2
1 3
1 4
2 3
1 4
Output Sample # 1: Copy
14 
11 

Solution:

We know that the linear base looking for maximum XOR and practice, you can know how to merge two roads linear base up.
We just all the elements in a linear way to the base of a linear-based approach to use the old road to join another group can be linear .
Then, when the processing of the way to handle multiplication LCA linear group, each query will maintain a ans array, when two points upward and the above processing method will jump linear array substrate according to stuffing ans.
Finally, in accordance with the template to find the biggest and XOR.


code:
  1 #include <bits/stdc++.h>
  2 #define N 20010
  3 #define ll long long
  4 using namespace std;
  5 
  6 ll sum;
  7 int n, q, tot;
  8 ll G[N], Head[N << 1], dep[N], ans[N];
  9 ll fa[N][21], p[N][21][62];
 10 
 11 struct Edge{
 12     int to, nxt; 
 13 }edge[N << 1];
 14 
 15 inline ll read()//不用快读会T..
 16 {
 17     char ch = getchar();
 18     ll x = 0, f = 1;
 19     while(ch > '9' || ch < '0')
 20     {
 21         if(ch == '-')
 22             f = -1;
 23         ch = getchar();
 24     }
 25     while(ch >= '0' && ch <= '9')
 26     {
 27         x = x * 10 + ch - '0';
 28         ch = getchar();
 29     }
 30     return x * f;
 31 }
 32 
 33 inline ll Max(ll a, ll b)//手打max省时
 34 {
 35     return a > b ? a : b;
 36 }
 37 
 38 inline void Add_edge(int u, int v)
 39 {
 40     edge[++tot].nxt = Head[u], edge[tot].to = v, Head[u] = tot;
 41     edge[++tot].nxt = Head[v], edge[tot].to = u, Head[v] = tot;
 42 }
 43 
 44 inline void Get_p(ll *a, ll val)//构造线性基
 45 {
 46     for(int i = 61; i >= 0; i--)
 47     {
 48         if((val >> i) & 1)
 49         {
 50             if(!a[i])
 51             {
 52                 a[i] = val;
 53                 break;
 54             }
 55             val ^= a[i];
 56         }
 57     } 
 58 }
 59 
 60 void Dfs(int u, int v)//信仰大法师预处理ᕦ(ò_óˇ)ᕤ
 61 {
 62     fa[v][0] = u;
 63     dep[v] = dep[u] + 1;
 64     for(int i = Head[v]; i; i = edge[i].nxt)
 65     {
 66         int w = edge[i].to;
 67         if(w == u)
 68             continue;
 69         Dfs(v, w);
 70     }
 71 }
 72 
 73 void Merge(ll *a, ll *b)//合并
 74 {
 75     for(int i = 61; i >= 0; i--)
 76     {
 77         if(b[i])
 78             Get_p(a, b[i]);
 79     }
 80 }
 81 
 82 void Get_lca()//lca预处理
 83 {
 84     for(int j = 1; j < 20; j++)
 85     {
 86         for(int i = 1; i <= n; i++)
 87         {
 88             fa[i][j] = fa[fa[i][j - 1]][j - 1];
 89             memcpy(p[i][j], p[i][j - 1], sizeof(p[i][j - 1]));
 90             Merge(p[i][j], p[fa[i][j - 1]][j - 1]);
 91         }
 92     }
 93 }
 94 
 95 inline void Lca(int u, int v)//查询lca并塞 ans
 96 {
 97     if(dep[u] < dep[v])
 98         swap(u, v);
 99     for(int i = 20; i >= 0; i--)
100         if(dep[fa[u][i]] >= dep[v])
101             Merge(ans, p[u][i]), u = fa[u][i];
102     if(u == v)
103     {
104         Merge(ans, p[u][0]);
105         return;
106     }
107     for(int i = 20; i >= 0; i--)
108         if(fa[u][i] != fa[v][i])
109         {
110             Merge(ans, p[u][i]), Merge(ans, p[v][i]);
111             u = fa[u][i], v = fa[v][i];
112         }
113     Merge(ans, p[u][0]), Merge(ans, p[v][0]), Merge(ans, p[fa[u][0]][0]);
114 }
115 
116 void Solve()
117 {
118     for(int i = 1; i <= q; i++)
119     {
120         memset(ans, 0, sizeof(ans));
121         int u = read(), v = read();
122         Lca(u, v);
123         sum = 0;
124         for(int j = 61; j >= 0; j--)
125             sum = Max(sum, sum ^ (ll)ans[j]);
126         printf("%lld\n", sum);
127     }
128 }
129 
130 int main()
131 {
132 
133     n = read(), q = read();
134     for(int i = 1; i <= n; i++)
135         Get_p(p[i][0], G[i] = read());
136     for(int i = 1; i <= n - 1; i++)
137     {
138         int u = read(), v = read();
139         Add_edge(u, v);
140     }
141     Dfs(0, 1);
142     Get_lca();
143     Solve();
144 
145     return 0;
146 }
 
   

 






Guess you like

Origin www.cnblogs.com/zhangbuang/p/11112764.html