ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

树上倍增学习总结

2020-07-14 17:02:53  阅读:229  来源: 互联网

标签:总结 树上 merge int LL fa ans -- 倍增


树上倍增:

  没讲的,直接上题

【SCOI2016】幸运数字(题目):

  倍增时合并一下线性基即可

 

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<iostream>
  4 #include<algorithm>
  5 using namespace std;
  6 
  7 typedef long long LL;
  8 
  9 const int N = 20010;
 10 
 11 int n, q;
 12 LL G[N], dep[N], ans[N];
 13 LL fa[N][21], p[N][21][62];
 14 int h[N], num[N << 1], nex[N << 1], dqx;
 15 
 16 inline void add(int a, int b)
 17 {
 18     num[dqx] = b;
 19     nex[dqx] = h[a];
 20     h[a] = dqx++;
 21 }
 22 
 23 inline void get_p(LL *a, LL val)
 24 {
 25     for (int i = 61; i >= 0; i--)
 26     {
 27         if ((val >> i) & 1)
 28         {
 29             if (!a[i])
 30             {
 31                 a[i] = val;
 32                 break;
 33             }
 34             val ^= a[i];
 35         }
 36     }
 37 }
 38 
 39 void dfs(int u, int f)
 40 {
 41     fa[u][0] = f;
 42     dep[u] = dep[f] + 1;
 43     for (int i = h[u]; ~i; i = nex[i])
 44     {
 45         int j = num[i];
 46         if (j == f) continue;
 47         dfs(j, u);
 48     }
 49 }
 50 
 51 void merge(LL* a, LL* b)
 52 {
 53     for (int i = 61; i >= 0; i--)
 54     {
 55         if (b[i]) get_p(a, b[i]);
 56     }
 57 }
 58 
 59 void get_lca()
 60 {
 61     for (int j = 1; j < 20; j++)
 62     {
 63         for (int i = 1; i <= n; i++)
 64         {
 65             fa[i][j] = fa[fa[i][j - 1]][j - 1];
 66             memcpy(p[i][j], p[i][j - 1], sizeof(p[i][j - 1]));
 67             merge(p[i][j], p[fa[i][j - 1]][j - 1]);
 68         }
 69     }
 70 }
 71 
 72 inline void LCA(int u, int v)
 73 {
 74     if (dep[u] < dep[v]) swap(u, v);
 75 
 76     for (int i = 20; i >= 0; i--)
 77     {
 78         if (dep[fa[u][i]] >= dep[v])
 79         {
 80             merge(ans, p[u][i]);
 81             u = fa[u][i];
 82         }
 83     }
 84         
 85     if (u == v)
 86     {
 87         merge(ans, p[u][0]);
 88         return;
 89     }
 90 
 91     for (int i = 20; i >= 0; i--)
 92     {
 93         if (fa[u][i] != fa[v][i])
 94         {
 95             merge(ans, p[u][i]), merge(ans, p[v][i]);
 96             u = fa[u][i], v = fa[v][i];
 97         }
 98     }
 99         
100     merge(ans, p[u][0]);
101     merge(ans, p[v][0]);
102     merge(ans, p[fa[u][0]][0]);
103 }
104 
105 int main()
106 {
107     scanf("%d%d", &n, &q);
108     for (int i = 1; i <= n; i++)
109     {
110         scanf("%lld", &G[i]);
111         get_p(p[i][0], G[i]);
112     }
113 
114     memset(h, -1, sizeof(h));
115     for (int i = 1; i <= n - 1; i++)
116     {
117         int a, b;
118         scanf("%d%d", &a, &b);
119         add(a, b), add(b, a);
120     }
121 
122     dfs(1, 0);
123     get_lca();
124 
125     for (int i = 1; i <= q; i++)
126     {
127         memset(ans, 0, sizeof(ans));
128 
129         int a, b;
130         scanf("%d%d", &a, &b);
131         LCA(a, b);
132         LL res = 0;
133 
134         for (int j = 61; j >= 0; j--) res = max(res, res ^ (LL)ans[j]);
135         printf("%lld\n", res);
136     }
137 }
View Code

 

标签:总结,树上,merge,int,LL,fa,ans,--,倍增
来源: https://www.cnblogs.com/Arrogant-Hierarch/p/13300068.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有