BZOJ 3612 HEOI2014 大工程 树链剖分求LCA的优越
来源:互联网 发布:差分方程matlab编程 编辑:程序博客网 时间:2024/05/17 08:46
虚树神马的网上已经讲了不少了 , 这里就多提啦 , 推荐看这个小伙伴的博客
本题是一个虚树的裸题 , 就不提示了。一般来说我不写这种题解烂大街的题目 , 但这次尝试打破了我以前的一个思维惯性 , 关于时间复杂度的误区。
为什么这题我写树链剖分求LCA呢? 因为我算错空间辣-_-#
当时我正在算倍增算法的空间 ,
不要紧 , 反正链剖空间低 , 我只有委曲求全的写了
此时我想起某次写倍增被卡时(最后被逼把倍增改成3进制才过)的经历 , 这次我决定试一试这两者的时间差别。 当我把
所以 , 这只能说明树剖的常数小 , 至于有多小 , 大家都可以脑补(某集训队论文分析 , 常数最大
我的代码里有两种写法 , 大家可以随意调试:
#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>#include <cmath>#include <string>#include <vector>#include <deque>#include <stack>#include <queue>#include <set>#include <map>#include <algorithm>#include <cassert>using namespace std;const int maxn = 1e6+1e2;const int INF = 0x3f3f3f3f;int n , m , dfsCnt , fa[maxn] , id[maxn] , bl[maxn] , dep[maxn] , Size[maxn] , book[maxn] , w[maxn];vector<int> g[maxn] , f[maxn];//int ace[maxn][20];//void pre()//{// for(int i=1;i<=n;i++) ace[i][0] = fa[i];// for(int i=1,j;i<20;i++) for(int k=1;k<=n;k++)// {// j = ace[k][i-1];// if(!j) continue;// ace[k][i] = ace[j][i-1];// }//}__inline int re() { int n = 0, ch = getchar(); bool flag = false; while(!isdigit(ch)) flag |= ch == '-', ch = getchar(); while(isdigit(ch)) n = n * 10 + ch - '0', ch = getchar(); return flag ? -n : n;}void dfs(int x){ id[x] = ++dfsCnt; Size[x] = 1; for(int i=0,t;i<g[x].size();i++) { t = g[x][i]; if(t == fa[x]) continue; fa[t] = x; dep[t] = dep[x] + 1; dfs(t); Size[x] += Size[t]; }}void dfs(int x , int num){ bl[x] = num; int mx=0 , w; for(int i=0,t;i<g[x].size();i++) { t = g[x][i]; if(t == fa[x]) continue; if(mx < Size[t]) w = t , mx = Size[t]; } if(mx) dfs(w, num); for(int i=0,t;i<g[x].size();i++) { t = g[x][i]; if(t == fa[x] || t == w) continue; dfs(t, t); }}//int lca(int x , int y)//{// if(dep[x] > dep[y]) swap(x, y);// for(int i=log2(dep[y]+1);i>=0;i--) if(ace[y][i] && dep[ace[y][i]] >= dep[x]) y = ace[y][i];// // if(x == y) return x;// // for(int i=log2(dep[x]+1),j,k;i>=0;i--)// {// j = ace[x][i];// k = ace[y][i];// if(j == k) continue;// x = j; y = k;// }// // return fa[x];//}int lca(int x , int y){ int f1 , f2; while(true) { f1 = bl[x]; f2 = bl[y]; if(f1 == f2) break; if(dep[f1] < dep[f2]) y = fa[f2]; else x = fa[f1]; } return dep[x] < dep[y] ? x : y;}long long r1;int r2 , r3 , mn[maxn] , mx[maxn] , s[maxn];void getRes(int x){ if(book[x]) { s[x] = 1; r1 += 1LL*dep[x]*m; mx[x] = mn[x] = dep[x]; } for(int i=0,j;i<f[x].size();i++) { j = f[x][i]; getRes(j); s[x] += s[j]; r1 -= 1LL*s[j]*s[j]*(dep[j] - dep[x]); r2 = min(r2 , mn[x] - dep[x] + mn[j] - dep[x]); r3 = max(r3 , mx[x] - dep[x] + mx[j] - dep[x]); mn[x] = min(mn[x] , mn[j]); mx[x] = max(mx[x] , mx[j]); } f[x].clear();}void clear(int x){ for(int i=0,j;i<f[x].size();i++) { j = f[x][i]; clear(j); } mn[x] = INF; mx[x] = -INF; s[x] = 0;}int q[maxn] , t;bool cmp(int x , int y) { return id[x] < id[y]; }void solve(){ sort(w+1, w+1+m, cmp); t = 0; for(int i=1,j;i<=m;i++) { if(!t) q[t++] = w[i]; else { if(lca(q[t-1], w[i]) == q[t-1]) q[t++] = w[i]; else { while(t>1 && dep[lca(q[t-2], w[i])] < dep[q[t-2]]) { f[q[t-2]].push_back(q[t-1]); t--; } f[j = lca(q[t-1], w[i])].push_back(q[t-1]) , t--; if(!t || q[t-1]!=j) q[t++] = j; if(!t || q[t-1]!=w[i]) q[t++] = w[i]; } } } while(t>1) f[q[t-2]].push_back(q[t-1]) , t--; r1 = 0; r2 = INF; r3 = -INF; clear(q[0]); getRes(q[0]); printf("%lld %d %d\n" , r1-1LL*dep[q[0]]*m*m , r2 , r3);}int main(int argc, char *argv[]) { cin>>n; for(int i=1,j,k;i<n;i++) { j = re(); k = re(); g[j].push_back(k); g[k].push_back(j); } dfs(1); dfs(1, 1);// pre(); int q; cin>>q; while(q--) { m = re(); for(int i=1;i<=m;i++) w[i] = re() , book[w[i]] = 1; solve(); for(int i=1;i<=m;i++) book[w[i]] = 0; } return 0;}
0 0
- BZOJ 3612 HEOI2014 大工程 树链剖分求LCA的优越
- bzoj 3611: [Heoi2014]大工程
- BZOJ 3611 HEOI2014 大工程 倍增LCA+单调栈+树形DP
- BZOJ 3611 [Heoi2014]大工程 虚树
- bzoj 3611 [Heoi2014]大工程 虚树 dp
- bzoj 3611 [Heoi2014]大工程 虚树DP
- 【BZOJ3611】【HEOI2014】大工程 LCA单调性 构造虚树
- 【BZOJ 3611】 [Heoi2014]大工程|虚树|树上DP
- bzoj 3611: [Heoi2014]大工程 虚树+树形dp
- 【BZOJ 3611】[Heoi2014]大工程 虚树+树形dp
- bzoj 3611: [Heoi2014]大工程 (虚树+树形DP)
- bzoj 3611: [Heoi2014]大工程(虚树+树形DP)
- bzoj3611: [Heoi2014]大工程
- 3611: [Heoi2014]大工程
- [BZOJ3611] [Heoi2014]大工程
- bzoj3611: [Heoi2014]大工程
- 3611: [Heoi2014]大工程
- bzoj3611 [Heoi2014]大工程
- HDU 3177 Crixalis's Equipment(很巧妙的贪心)
- Xcode项目依赖
- An unexpected error prevented the server from fulfilling your request. (HTTP 500)
- Gallery的整体架构
- Android ORM应用开发框架KJFrameForAndroid使用详解
- BZOJ 3612 HEOI2014 大工程 树链剖分求LCA的优越
- UILable,UIButton字体加粗
- 乱码终极解决大全
- Android初试--Android中的ContentProvider(3)
- httpd.conf配置后php7,出现apache无法启动的现象
- 递归写法总结
- Big vs Big(链表)
- 机器学习实战(5)--SVM(Support vector machine)(二)
- struts2不显示.do .action 后缀