学习树链剖分的第一题,第二个dfs忘记递归了(太蠢),re了两发,改过来以后就1A了。

学习树链剖分可以参考这篇博客:http://blog.sina.com.cn/s/blog_7a1746820100wp67.html 个人感觉写得非常好!!!

树链剖分听起来很吊,其实就是把数边扔到线段树上,然后搞出一点事情来。主要就是一个重儿子,重链,从而使复杂度降到了(logn)。这个非常关键。关于初始化建树:先剖分,求出size,son,w,top,fa,dep数组,就能把树链扔到线段树树上实现了,这个过程也就是两个dfs实现。然后就是简单的区间修改的问题了。(再次感觉那篇博客写得太好了)

树的边权的问题可以转化为树链剖分的问题!!!

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <cmath>
#include <map>
#define LL long long
#define FOR(i,x,y)  for(int i = x;i < y;i ++)
#define IFOR(i,x,y) for(int i = x;i > y;i --)
#define lrt rt<<1
#define rrt rt<<1|1
#define lson rt<<1,l,mid
#define rson rt<<1|1,mid+1,r
#define MAXN 11000using namespace std;int n,val[MAXN];int head[MAXN<<1],edge_cnt;
map <int,int> mat;struct Edge{int u,v,idd,value;int nt;
}edge[MAXN<<1];void add_edge(int u,int v,int idd){edge[edge_cnt].u = u;edge[edge_cnt].v = v;edge[edge_cnt].idd = idd;edge[edge_cnt].nt = head[u];head[u] = edge_cnt++;
}int sz[MAXN],son[MAXN],fa[MAXN],dep[MAXN],top[MAXN],id[MAXN],w[MAXN],val0[MAXN],totw;void dfs1(int u,int father,int depth){sz[u] = 1;  dep[u] = depth;  fa[u] = father;int idd = -1,maxx = -1;for(int i = head[u];i != -1;i = edge[i].nt){int v = edge[i].v;if(v == father)  continue;id[v] = edge[i].idd;dfs1(v,u,depth+1);sz[u] += sz[v];if(sz[v] > maxx)    {idd = v;maxx = sz[v];}}son[u] = idd;
}void dfs2(int u,int father){if(son[u] == -1)    return;top[son[u]] = top[u];w[son[u]] = ++totw;val[totw] = val0[id[son[u]]];mat[id[son[u]]] = totw;dfs2(son[u],u);for(int i = head[u];i != -1;i = edge[i].nt){int v = edge[i].v;if(v == father) continue;if(v == son[u]) continue;top[v] = v;w[v] = ++totw;val[totw] = val0[id[v]];mat[id[v]] = totw;dfs2(v,u);}
}struct Tree{int l,r;int maxx;
}tree[MAXN<<2];void PushUp(int rt){tree[rt].maxx = max(tree[lrt].maxx,tree[rrt].maxx);
}void Build(int rt,int l,int r){tree[rt].l = l; tree[rt].r = r;if(l == r){tree[rt].maxx = val[l];return;}int mid = (l+r)>>1;Build(lson);Build(rson);PushUp(rt);
}void Modify(int rt,int x,int value){if(tree[rt].l == tree[rt].r){tree[rt].maxx = value;return;}int mid = (tree[rt].l + tree[rt].r)>>1;if(x <= mid)    Modify(lrt,x,value);else Modify(rrt,x,value);PushUp(rt);
}int Query(int rt,int l,int r){if(tree[rt].l == l && tree[rt].r == r){return tree[rt].maxx;}int mid = (tree[rt].l + tree[rt].r)>>1;if(r <= mid)    return Query(lrt,l,r);else if(l > mid)    return Query(rrt,l,r);else return max(Query(lson),Query(rson));
}int solve(int l,int r){int ans = -1;while(top[l] != top[r]){if(dep[top[l]] >= dep[top[r]]){ans = max(ans,Query(1,w[top[l]],w[l]));l = fa[top[l]];}else{ans = max(ans,Query(1,w[top[r]],w[r]));r = fa[top[r]];}}if(l == r)  return ans;if(dep[l] >= dep[r]){return max(ans,Query(1,w[r]+1,w[l]));}else return max(ans,Query(1,w[l]+1,w[r]));
}int main(){//freopen("test.in","r",stdin);int T;scanf("%d",&T);while(T--){scanf("%d",&n);int u,v,value;memset(head,-1,sizeof(head));edge_cnt = 0;FOR(i,1,n){scanf("%d%d%d",&u,&v,&value);add_edge(u,v,i);add_edge(v,u,i);val0[i] = value;}dfs1(1,-1,1);totw = 0;top[1] = 1;dfs2(1,-1);Build(1,1,totw);char op[10];while(~scanf("%s",op) && strcmp(op,"DONE")){if(strcmp(op,"QUERY") == 0){int l,r;scanf("%d%d",&l,&r);printf("%d\n",solve(l,r));}else{int x,value;scanf("%d%d",&x,&value);Modify(1,mat[x],value);}}}return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

转载于:https://www.cnblogs.com/hqwhqwhq/p/4811885.html

SPOJ 375 树链剖分学习相关推荐

  1. POJ 3237 树链剖分学习(树链剖分小结)

    一个地方wa了3发,找了一组数组发现的错误,太蠢,就是两个人数作交换写成了 a=b ,b=a.最近智商真是感人.这道题是由spoj375这题改编的,多了一个取反的操作,这个操作只需要多维护一个最小值就 ...

  2. 【高级数据结构】[SPOJ QTREE]树链剖分/动态树各一模板

    题目: 树链剖分: #include<cstdio> #include<cstring> #include<algorithm> using namespace s ...

  3. 【暖*墟】#树链剖分# 树链剖分学习与练习

    树链剖分 树链剖分是一种优化,将树上最常经过的几条链划为重点,用线段树来优化区间修改和查询. 并且因为在一棵子树中dfs序是连续的,并且在任意一条重链上,dfs序也是连续的, 可以认为轻链是单点修改, ...

  4. ZJOI2008 树的统计 树链剖分学习

    水题,这次都没有给我傻逼的机会了,1A过了.直接上代码了 #include <iostream> #include <cstdio> #include <cstring& ...

  5. 【SPOJ-QTREE】树链剖分

    树链剖分学习 https://blog.csdn.net/u013368721/article/details/39734871 https://www.cnblogs.com/George1994/ ...

  6. SPOJ 375. Query on a tree (树链剖分)

    题目链接: http://www.spoj.com/problems/QTREE/ 375. Query on a tree Problem code: QTREE You are given a t ...

  7. spoj 375 Query on a tree (树链剖分)

    题目链接: http://www.spoj.com/problems/QTREE/ 题意: 给一颗树,每条边有一个权值.有两种操作: 1.修改某条边的值: 2.询问a.b两点路径上边权的最大值. 分析 ...

  8. SPOJ 375 query on a tree 树链剖分

    题意: 给一棵树型数据结构 ①支持修改边的权值      ②支持成段边权最值查询 树链剖分入门题. 树链剖分+线段树 用的notonlysuccess的线段树--不开结构体事先预处理的那种 我以前写的 ...

  9. SPOJ - QTREE3Query on a tree again!——树链剖分

    [题目描述] SPOJ - QTREE3Query on a tree again! [题目分析] 题目要求是输出从111到xxx的路径上遇到的第一个黑色的点.我们可以用树链剖分(不了解的同学请出门左 ...

最新文章

  1. Rocksdb iterator和snapshot 接口
  2. Google推出HTML 5练兵场 提供详尽代码示例,互联网营销
  3. 分布式系统消息中间件——RabbitMQ的使用基础篇
  4. 每日两SQL(4),欢迎交流~
  5. android http常用配置,Android中Retrofit+OkHttp进行HTTP网络编程的使用指南
  6. 高仿114la网址导航源码完整最新版
  7. tomcat source code in eclipse
  8. gps天线拆解图片_威旺M20如何拆解中控导航及找出gps天线
  9. 机器学习必看的28个视频
  10. web-登陆界面html-数据库
  11. 毕业论文用到的在线网站
  12. linux zip加压到文件夹,Linux下zip压缩和unzip解压缩命令全解
  13. 前端语音转文字实践总结
  14. ai怎么做盒子效果图_ai怎么制作包装盒? Ai贴图工具制作包装盒的实例教程
  15. 各省市大学 全国各个省市重点民办本专科大学
  16. Go开源说第十七期 分布式事务DTM
  17. 汇佳学校|牛畅:帕森斯摄影专业,累计130万奖学金,我用照片沉淀时间
  18. 谁发明了验证码?你出来 保证不打死你
  19. SpringCloud这35问,弄懂了面试官都不得不夸你一句
  20. 我的操作系统梦破灭了

热门文章

  1. ViewPager之引导界面---实现欢迎引导页面
  2. golang中的随机数
  3. linux命令more
  4. MySQL笔记3:深入理解MySQL中的NULL
  5. 嵌入式中的中断服务程序
  6. Linux编程下open()函数的用法
  7. 线程:volatile关键字
  8. python五:运算符
  9. SWIFT问题很大,第4家受害银行浮出水面
  10. ActiveReports 报表中 RDF 文件解析