题目:Query on a tree

题意:给定一棵树,告诉了每条边的权值,然后给出两种操作:

(1)把第i条边的权值改为val

(2)询问a,b路径上权值最大的边

分析:本题与HDU3966差不多,区别就是:HDU3966是告诉树中点权的值,这里是边权。

所以我们可以转化,用边的孩子节点来表示该边。

#include <iostream>
#include <string.h>
#include <algorithm>
#include <stdio.h> using namespace std;
const int N=50010;
const int INF=1<<30; int n,tim; int num[N],siz[N],top[N],son[N];
int dep[N],tid[N],rank[N],fa[N];
int head[N],to[2*N],next[2*N],w[2*N],edge; struct Edge
{
int u,v,c;
};
Edge tmp[2*N]; void Init()
{
memset(head,-1,sizeof(head));
memset(son,-1,sizeof(son));
tim=0;
edge=0;
} void addedge(int u,int v,int c)
{
to[edge]=v,w[edge]=c,next[edge]=head[u],head[u]=edge++;
to[edge]=u,w[edge]=c,next[edge]=head[v],head[v]=edge++;
} //树链剖分部分
void dfs1(int u,int father,int d)
{
dep[u]=d;
fa[u]=father;
siz[u]=1;
for(int i=head[u]; ~i; i=next[i])
{
int v=to[i];
if(v!=father)
{
dfs1(v,u,d+1);
siz[u]+=siz[v];
if(son[u]==-1||siz[v]>siz[son[u]])
son[u]=v;
}
}
} void dfs2(int u,int tp)
{
top[u]=tp;
tid[u]=++tim;
rank[tid[u]]=u;
if(son[u]==-1) return;
dfs2(son[u],tp);
for(int i=head[u]; ~i; i=next[i])
{
int v=to[i];
if(v!=son[u]&&v!=fa[u])
dfs2(v,v);
}
} //线段树部分
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1 int MAX[4*N]; void PushUP(int rt)
{
MAX[rt]=max(MAX[rt<<1],MAX[rt<<1|1]);
} void Build(int l,int r,int rt)
{
if(l==r)
{
MAX[rt]=num[l];
return;
}
int mid=(l+r)>>1;
Build(lson);
Build(rson);
PushUP(rt);
} void Update(int l,int r,int rt,int p,int val)
{
if(l==r)
{
MAX[rt]=val;
return;
}
int mid=(l+r)>>1;
if(p<=mid)
Update(lson,p,val);
else
Update(rson,p,val);
PushUP(rt);
} int Query(int l,int r,int rt,int L,int R)
{
if(L<=l&&R>=r)
return MAX[rt];
int mid=(l+r)>>1;
int ret=-INF;
if(L<=mid) ret=max(ret,Query(lson,L,R));
if(R>mid) ret=max(ret,Query(rson,L,R));
return ret;
} void Change(int x,int val)
{
if(dep[tmp[x].u]>dep[tmp[x].v])
Update(2,n,1,tid[tmp[x].u],val);
else
Update(2,n,1,tid[tmp[x].v],val);
} int query(int x,int y)
{
int ans=-INF;
while(top[x]!=top[y])
{
if(dep[top[x]]<dep[top[y]]) swap(x,y);
ans=max(ans,Query(2,n,1,tid[top[x]],tid[x]));
x=fa[top[x]];
}
if(dep[x]>dep[y]) swap(x,y);
if(x!=y) ans=max(ans,Query(2,n,1,tid[x]+1,tid[y]));
return ans;
} int main()
{
char oper[15];
int a,b,c,t;
scanf("%d",&t);
while(t--)
{
Init();
scanf("%d",&n);
for(int i=1; i<n; i++)
{
scanf("%d%d%d",&a,&b,&c);
tmp[i].u=a;tmp[i].v=b;tmp[i].c=c;
addedge(a,b,c);
}
dfs1(1,1,1);
dfs2(1,1);
//用边的孩子节点来表示该边
for(int i=1;i<n;i++)
{
if(dep[tmp[i].u]>dep[tmp[i].v])
num[tid[tmp[i].u]]=tmp[i].c;
else
num[tid[tmp[i].v]]=tmp[i].c;
}
Build(2,n,1);
while(1)
{
scanf("%s",oper);
if(oper[0]=='D') break;
scanf("%d%d",&a,&b);
if(oper[0]=='Q')
printf("%d\n",query(a,b));
else
Change(a,b);
}
}
return 0;
}

SPOJ375(树链剖分)的更多相关文章

  1. Cogs 1672. [SPOJ375 QTREE]难存的情缘 LCT,树链剖分,填坑计划

    题目:http://cojs.tk/cogs/problem/problem.php?pid=1672 1672. [SPOJ375 QTREE]难存的情缘 ★★★☆   输入文件:qtree.in  ...

  2. 树链剖分边权模板spoj375

    树链剖分是树分解成多条链来解决树上两点之间的路径上的问题 如何求出树链:第一次dfs求出树上每个结点的大小和深度和最大的儿子,第二次dfs就能将最大的儿子串起来并hash(映射)到线段树上(或者其他数 ...

  3. SPOJ375.QTREE树链剖分

    题意:一个树,a b c 代表a--b边的权值为c.CHANGE x y  把输入的第x条边的权值改为y,QUERY x y 查询x--y路径上边的权值的最大值. 第一次写树链剖分,其实树链剖分只能说 ...

  4. [SPOJ375]QTREE - Query on a tree【树链剖分】

    题目描述 给你一棵树,两种操作. 修改边权,查找边权的最大值. 分析 我们都知道,树链剖分能够维护点权. 而且每一条边只有一个,且唯一对应一个儿子节点,那么就把信息放到这个儿子节点上. 注意,lca的 ...

  5. BZOJ 3626: [LNOI2014]LCA [树链剖分 离线|主席树]

    3626: [LNOI2014]LCA Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 2050  Solved: 817[Submit][Status ...

  6. BZOJ 1984: 月下“毛景树” [树链剖分 边权]

    1984: 月下“毛景树” Time Limit: 20 Sec  Memory Limit: 64 MBSubmit: 1728  Solved: 531[Submit][Status][Discu ...

  7. codevs 1228 苹果树 树链剖分讲解

    题目:codevs 1228 苹果树 链接:http://codevs.cn/problem/1228/ 看了这么多树链剖分的解释,几个小时后总算把树链剖分弄懂了. 树链剖分的功能:快速修改,查询树上 ...

  8. 并查集+树链剖分+线段树 HDOJ 5458 Stability(稳定性)

    题目链接 题意: 有n个点m条边的无向图,有环还有重边,a到b的稳定性的定义是有多少条边,单独删去会使a和b不连通.有两种操作: 1. 删去a到b的一条边 2. 询问a到b的稳定性 思路: 首先删边考 ...

  9. 树链剖分+线段树 CF 593D Happy Tree Party(快乐树聚会)

    题目链接 题意: 有n个点的一棵树,两种操作: 1. a到b的路径上,给一个y,对于路径上每一条边,进行操作,问最后的y: 2. 修改某个条边p的值为c 思路: 链上操作的问题,想树链剖分和LCT,对 ...

随机推荐

  1. Android的BUG(四) - Android app的卡死问题

    做android,免不了要去运行一些跑分程序,常用的跑分程序有quadrant(象限),nbench,安兔兔等.作为系统工程师,对这些跑分 程序都非常的不屑,这个只能是一个不客观的参考,但客户都喜欢拿 ...

  2. NDK如何调试系统核心动态库(无系统源码的情况)

    版权归薛定諤耗子所有,转载请表明出处. 1,有源码,需要导入符号表 2,没有源码,如何调试 1)运行ndk-gdb:../../ndk-gdb --verbose --launch=com.examp ...

  3. SUSAN检测算子

    USAN区域(核同值区):和核像素的灰度相同会相信的模板像素的区域. 利用这个区域的尺寸.重心.二阶矩等可以帮助检测图像的边缘和角点.利用USAN的面积作为特征可以起到增强边缘和角点的效果. 该方法不 ...

  4. Jquery学习笔记:利用parent和parents方法获取父节点

    通过选择器一般只能获取指定标识的节点,或者获取子节点. 有些场景下,往往需要根据当前节点找到满足条件的父节点.这个可以通过相应的方法来实现. 1.parent方法 该方法可以获取元素的直接父节点. 我 ...

  5. uoj Goodbye Jiawu

    这次比赛真是太伤我心了. 比(惨)赛(不)结(忍)果(睹) 完挂感言 uoj round 5已经挂了一次了,没想到还要再挂第二次. 这次比赛的期望得分是\(100+100+100+70+10\)的.没 ...

  6. 京香julia_百度百科

    京香julia_百度百科 京香julia

  7. 【C/C++多线程编程之四】终止pthread线程

    多线程编程之终止pthread线程       Pthread是 POSIX threads 的简称,是POSIX的线程标准.           终止线程似乎是多线程编程的最后一步,但绝不是本系列教 ...

  8. Swift UI开发初探

    今天凌晨Apple刚刚发布了Swift编程语言,Swift是供iOS和OS X应用编程的新编程语言.相信很多开发者都在学习这门新语言. 废话不多说,下面我就来学习使用Swift创建一个简单的UI应用程 ...

  9. MFC对话框Style说明

    Popup:弹出窗口 Overlapped:重叠窗口 Child:子窗口 在它们之间并没有太多内在的差异,但是使用不同的窗口风格,它们的外观是 不同的. 重叠窗口通常用于建立应用程序主窗口.事实上,有 ...

  10. linux 压缩和解压文件

    一.压缩:20120715文件下面所有的文件 如下: tar -zcvf 20120715.tar.gz  20120715* 二.解压20120715.tar.gz压缩包 如下: tar -xzvf ...