题目链接:点击查看

题目大意:给出一棵由n个点组成的树,再给出数个操作,每次操作分为下列几种类型:

  1. QUERY x y:询问点x-点y这条路径上的所有边权的最大值
  2. CHANGE x y:将第x条边的权值改为y
  3. DONE:退出操作

题目分析:做做板子题练练代码熟练度吧,起码模板能够熟练默写后,再写树链剖分的函数就不太会犯低级错误了

回到这个题目上,因为是查询点x-点y这条路径上的最值,不难想到要用线段树维护一下最大值,想要用线段树的前提就是要有连续区间,我们用树链剖分将整棵树先剖一下,然后剩下的就是基本操作了

这个题目还是注意一下映射的关系,我都习惯在注释中提前写明白,不然自己在写代码的时候也会一不小心犯糊涂

代码:

#include<iostream>
#include<cstdlib>
#include<string>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<climits>
#include<cmath>
#include<cctype>
#include<stack>
#include<queue>
#include<list>
#include<vector>
#include<set>
#include<map>
#include<sstream>
using namespace std;typedef long long LL;const int inf=0x3f3f3f3f;const int N=1e4+100;int n;struct Node
{int to,w,id;Node(int TO,int W,int ID){to=TO;w=W;id=ID;}
};vector<Node>node[N];int fa[N],deep[N],son[N],num[N],val[N],rk[N];//val[节点]=权值 rk[编号]=节点 void dfs1(int u,int f,int dep)
{son[u]=-1;deep[u]=dep;num[u]=1;fa[u]=f;for(auto i:node[u]){int v=i.to;int w=i.w;int id=i.id;if(v==f)continue;dfs1(v,u,dep+1);val[v]=w;rk[id]=v;num[u]+=num[v];if(son[u]==-1||num[son[u]]<num[v])son[u]=v;}
}int top[N],id[N],idd[N],cnt;//id[节点]=编号 idd[编号]=节点 void dfs2(int u,int f,int root)
{top[u]=root;id[u]=++cnt;idd[cnt]=u;if(son[u]!=-1)dfs2(son[u],u,root);for(auto i:node[u]){int v=i.to;if(v==f||v==son[u])continue;dfs2(v,u,v);}
}struct tree
{int l,r,mmax;
}tree[N<<2];void pushup(int k)
{tree[k].mmax=max(tree[k<<1].mmax,tree[k<<1|1].mmax);
} void build(int k,int l,int r)
{tree[k].l=l;tree[k].r=r;if(l==r){tree[k].mmax=val[idd[l]];return;}int mid=l+r>>1;build(k<<1,l,mid);build(k<<1|1,mid+1,r);pushup(k);
}void update(int k,int pos,int val)
{if(tree[k].l==tree[k].r){tree[k].mmax=val;return;}int mid=tree[k].l+tree[k].r>>1;if(mid>=pos)update(k<<1,pos,val);elseupdate(k<<1|1,pos,val);pushup(k);
}int query(int k,int l,int r)
{if(tree[k].r<l||tree[k].l>r)return -inf;if(tree[k].l>=l&&tree[k].r<=r)return tree[k].mmax;return max(query(k<<1,l,r),query(k<<1|1,l,r));
}int solve(int u,int v)
{int ans=-inf;while(top[u]!=top[v]){if(deep[top[u]]<deep[top[v]])swap(u,v);ans=max(ans,query(1,id[top[u]],id[u]));u=fa[top[u]];}if(u==v)return ans;if(deep[u]<deep[v])swap(u,v);ans=max(ans,query(1,id[v]+1,id[u]));return ans;
} void init()
{for(int i=1;i<=n;i++)node[i].clear();cnt=0;
}int main()
{
//  freopen("input.txt","r",stdin);
//  ios::sync_with_stdio(false);int w;cin>>w;while(w--){scanf("%d",&n);init();for(int i=1;i<n;i++){int a,b,c;scanf("%d%d%d",&a,&b,&c);node[a].push_back(Node(b,c,i));node[b].push_back(Node(a,c,i));}dfs1(1,0,0);dfs2(1,0,1);build(1,1,n);char s[10];while(scanf("%s",s)!=EOF&&s[0]!='D'){if(s[0]=='C'){int x,y;scanf("%d%d",&x,&y);update(1,id[rk[x]],y);}else{int x,y;scanf("%d%d",&x,&y);printf("%d\n",solve(x,y));}}}return 0;
}

SPOJ - QTREE Query on a tree(树链剖分+线段树)相关推荐

  1. CodeForces - 609E Minimum spanning tree for each edge(最小生成树+树链剖分+线段树/树上倍增)

    题目链接:点击查看 题目大意:给出一张 n 个点和 m 条边组成的无向图,现在询问包含每一条边的最小生成树 题目分析:考虑求解次小生成树的思路: 求出最小生成树 ans 枚举每一条非树边 ( u , ...

  2. 【BZOJ-2325】道馆之战 树链剖分 + 线段树

    2325: [ZJOI2011]道馆之战 Time Limit: 40 Sec  Memory Limit: 256 MB Submit: 1153  Solved: 421 [Submit][Sta ...

  3. CodeForces - 160D Edges in MST(思维+tarjan/树链剖分+线段树)

    题目链接:点击查看 题目大意:给出一张 n 个点 m 条边组成的带权无向图,现在对于每条边来说,确定一下其分类: 一定是最小生成树上的边 可能是最小生成树上的边 一定不是最小生成树的边 题目分析:两种 ...

  4. P2486 [SDOI2011]染色(树链剖分+线段树)

    题干描述 输入描述 输出格式 对于每个询问操作,输出一行答案. 输入输出样例 输入 #1 复制 6 5 2 2 1 2 1 1 1 2 1 3 2 4 2 5 2 6 Q 3 5 C 2 1 1 Q ...

  5. BZOJ4127Abs——树链剖分+线段树

    题目描述 给定一棵树,设计数据结构支持以下操作 1 u v d 表示将路径 (u,v) 加d 2 u v 表示询问路径 (u,v) 上点权绝对值的和 输入 第一行两个整数n和m,表示结点个数和操作数 ...

  6. 【BZOJ2243】[SDOI2011]染色 树链剖分+线段树

    [BZOJ2243][SDOI2011]染色 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的 ...

  7. HDU 2460 Network(双连通+树链剖分+线段树)

    HDU 2460 Network 题目链接 题意:给定一个无向图,问每次增加一条边,问个图中还剩多少桥 思路:先双连通缩点,然后形成一棵树,每次增加一条边,相当于询问这两点路径上有多少条边,这个用树链 ...

  8. BZOJ2325[ZJOI2011]道馆之战——树链剖分+线段树

    题目描述 口袋妖怪(又名神奇宝贝或宠物小精灵)红/蓝/绿宝石中的水系道馆需要经过三个冰地才能到达馆主的面前,冰地中 的每一个冰块都只能经过一次.当一个冰地上的所有冰块都被经过之后,到下一个冰地的楼梯才 ...

  9. BZOJ3862Little Devil I——树链剖分+线段树

    题目大意: 给一棵树,每条边可能是黑色或白色(起始都是白色),有三种操作: 1.将u到v路径上所有边颜色翻转(黑->白,白->黑) 2.将只有一个点在u到v路径上的边颜色翻转 3.查询u到 ...

  10. YbtOJ-染色计划【树链剖分,线段树,tarjan】

    正题 题目大意 给出nnn个点的一棵树,每个点有个颜色aia_iai​,你每次可以选择一个颜色全部变成另一个颜色. 求最少多少次操作可以把一种颜色变成一个完整的连通块. 1≤k≤n≤2×1051\le ...

最新文章

  1. 如何删除/删除Python不为空的文件夹?
  2. 对IFeatureClass的选择结果进行再次选择及排序
  3. 登录案例_BeanUtils基本使用
  4. 5.2jquery案例2
  5. 四年级计算机笔试题,四年级计算机考试卷.doc
  6. 课下作业:评估输入法(搜狗)
  7. 全国超300所大学图书馆收藏本人作品
  8. 杨奇龙 mysql 分区_MySQL Group Replication 入坑指北 | By杨奇龙
  9. 在网页输出10的阶乘.php,VB 用for循环语句编写程序,计算和输出10的阶乘
  10. 前端开发者的必备好书:CSS世界三部曲,你都知道吗?
  11. Linux下 lnmp一键安装
  12. FreeRTOS任务管理
  13. IE 零日漏洞风险评估
  14. OSChina 周四乱弹 ——因为女同事衣服穿的薄 所以老板发现我没上班?
  15. 零基础建站教程(二)宝塔面板的使用和CMS的安装
  16. 10个团建小游戏备选方案
  17. TensorFlow中用深度学习修复图像
  18. Spring集成Hibernate5_03-HibernateDaoSupport
  19. 04.Nginx代理(学习)
  20. 01_行销(Marketing)里的有用的KPI-转换率 (Conversion Rate)

热门文章

  1. Nacos OPEN API配置管理测试
  2. Nginx的rewrite案例之防盗链
  3. 分布式会话拦截器2 - 会话判断
  4. 依赖版本控制-pom文件介绍
  5. Spring编程模型:Spring实现了哪些编程模型?
  6. ServletContext_概述
  7. Spring Session实战3
  8. Hmac - Java加密与安全
  9. SpringBoot AOP拦截器
  10. Java8函数式编程(3)--规约操作