题目大意:

  一棵树,有边权,有两个操作:1.修改一条边的权值;2.询问两点间路径上的边的权值的最大值。

思路:

  十分裸的树链剖分+线段树,无非是边权要放到深度大的一端的点上,但是有两个坑爹的地方,改了好久:

  1.数组定义10000和40000会TLE,要乘10;

  2.以前的树剖求解的最后是这样的:

    if (deep[x]>deep[y]) swap(x,y);
return max(ans,MAX(,n,id[x],id[y],));

  但是WA了,膜拜大神后发现这样就AC了:

    if (x==y) return ans;
if (dep[x]>dep[y]) swap(x,y);
return max(ans,ask(,n,id[x]+,id[y],));

  以前应该是错了。

代码:

 #include<cstdio>
#include<iostream>
using namespace std;
const int M=;
int n,cnt,t,p[M],hea[M],size[M],v[M],a[M],b[M],c[M],nex[M],dep[M],top[M],id[M],tree[M<<];
char s[M]; bool vis[M]; int read()
{
int x=; bool f=; char ch=getchar();
while (ch<'' || ch>'') { if (ch=='-') f=; ch=getchar(); }
while (ch>='' && ch<='') x=(x<<)+(x<<)+ch-,ch=getchar();
return f?-x:x;
} void add(int x,int y) { v[++cnt]=y,nex[cnt]=hea[x],hea[x]=cnt; } void dfs1(int x,int fa,int h)
{
size[x]=,dep[x]=h,p[x]=fa;
for (int i=hea[x],y;i;i=nex[i])
if ((y=v[i])^fa) dfs1(y,x,h+),size[x]+=size[y];
} void dfs2(int x,int chain)
{
int i,k=,y;
id[x]=++t,top[x]=chain;
for (i=hea[x];i;i=nex[i])
if (size[y=v[i]]>size[k] && y^p[x]) k=y;
if (!k) return; dfs2(k,chain);
for (i=hea[x];i;i=nex[i])
if ((y=v[i])^p[x] && k^y) dfs2(y,y);
} void push_up(int k) { tree[k]=max(tree[k<<],tree[k<<|]); } void change(int L,int R,int x,int val,int cur)
{
if (L==R) { tree[cur]=val; return; }
int mid=L+R>>;
if (x>mid) change(mid+,R,x,val,cur<<|);
else change(L,mid,x,val,cur<<);
push_up(cur);
} int ask(int L,int R,int l,int r,int cur)
{
if (l<=L && R<=r) return tree[cur];
int mid=L+R>>;
if (r<=mid) return ask(L,mid,l,r,cur<<);
else if (l>mid) return ask(mid+,R,l,r,cur<<|);
else return max(ask(L,mid,l,mid,cur<<),ask(mid+,R,mid+,r,cur<<|));
} int qry(int x,int y)
{
int ans=-;
for (;top[x]^top[y];x=p[top[x]])
{
if (dep[top[x]]<dep[top[y]]) swap(x,y);
ans=max(ans,ask(,n,id[top[x]],id[x],));
}
if (x==y) return ans;
if (dep[x]>dep[y]) swap(x,y);
return max(ans,ask(,n,id[x]+,id[y],));
} int main()
{
for (int T=read(),i;T;--T)
{
n=read(),cnt=t=;
for (i=;i<=n;++i) hea[i]=;
for (i=;i<n;++i)
{
a[i]=read(),b[i]=read(),c[i]=read();
add(a[i],b[i]),add(b[i],a[i]);
}
dfs1(,,),dfs2(,);
for (i=;i<n;++i)
{
if (dep[a[i]]<dep[b[i]]) swap(a[i],b[i]);
change(,n,id[a[i]],c[i],);
}
for (;;)
{
scanf("%s",s);
if (s[]=='D') break;
int x=read(),y=read();
if (s[]=='C') change(,n,id[a[x]],y,);
if (s[]=='Q') printf("%d\n",qry(x,y));
}
}
return ;
}

SPOJ - QTREE Query on a tree题解的更多相关文章

  1. SPOJ QTREE Query on a tree 树链剖分+线段树

    题目链接:http://www.spoj.com/problems/QTREE/en/ QTREE - Query on a tree #tree You are given a tree (an a ...

  2. spoj QTREE - Query on a tree(树链剖分+线段树单点更新,区间查询)

    传送门:Problem QTREE https://www.cnblogs.com/violet-acmer/p/9711441.html 题解: 树链剖分的模板题,看代码比看文字解析理解来的快~~~ ...

  3. SPOJ QTREE Query on a tree --树链剖分

    题意:给一棵树,每次更新某条边或者查询u->v路径上的边权最大值. 解法:做过上一题,这题就没太大问题了,以终点的标号作为边的标号,因为dfs只能给点分配位置,而一棵树每条树边的终点只有一个. ...

  4. SPOJ QTREE Query on a tree VI

    You are given a tree (an acyclic undirected connected graph) with n nodes. The tree nodes are number ...

  5. SPOJ QTREE Query on a tree V

    You are given a tree (an acyclic undirected connected graph) with N nodes. The tree nodes are number ...

  6. SPOJ QTREE Query on a tree ——树链剖分 线段树

    [题目分析] 垃圾vjudge又挂了. 树链剖分裸题. 垃圾spoj,交了好几次,基本没改动却过了. [代码](自带常数,是别人的2倍左右) #include <cstdio> #incl ...

  7. SPOJ QTREE - Query on a tree 【树链剖分模板】

    题目链接 引用到的大佬博客 代码来自:http://blog.csdn.net/jinglinxiao/article/details/72940746 具体算法讲解来自:http://blog.si ...

  8. SPOJ QTREE Query on a tree

    题意:给一颗n个点的树,有两种操作CHANGE i ti : 把第i条边的权变为tiQUERY a b : 问点a 到 点b 之间的边的最大权 思路:树剖处理边权.由于是边,所以只需要把边权处理到子节 ...

  9. SPOJ QTREE Query on a tree V ——动态点分治

    [题目分析] QTREE4的弱化版本 建立出分治树,每个节点的堆表示到改点的最近白点距离. 然后分治树上一直向上,取min即可. 正确性显然,不用担心出现在同一子树的情况(不会是最优解),请自行脑补. ...

随机推荐

  1. Python的数据类型:list和tuple

    今天开始认真的学习python. 1.list类型 list是python的一种数据类型,它是一种有序列表,可以随时添加和删除其中的元素. 1.1 list类型的特征 list类型内的成员类型可以相同 ...

  2. jmeter(三)参数传递

    [一]参数化 录制脚本中有登录操作,需要输入用户名和密码,假如系统不允许相同的用户名和密码同时登录,或者想更好的模拟多个用户来登录系统. 这个时候就需要对用户名和密码进行参数化,使每个虚拟用户都使用不 ...

  3. 1270 数组的最大代价 dp

    http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1270&judgeId=194704 一开始贪心,以为就两种情况, ...

  4. 【Mybatis】环境搭建

    SqlMapConfig.xml(MyBatis配置文件) <?xml version="1.0" encoding="UTF-8" ?> < ...

  5. [BZOJ1046][HAOI2007]上升序列 DP+贪心

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1046 我们先求出对于每一个数字作为开头的LCS的长度f[i],最长的f[i]为mxlen. ...

  6. SQL 触发器-如何查看当前数据库中有哪些触发器

    在查询分析器中运行: use 数据库名goselect * from sysobjects where xtype='TR' sysobjects 保存着数据库的对象,其中 xtype 为 TR 的记 ...

  7. ASP.NET控件的ID,ClientID,UniqueId的区别

    一般情况下三者相同(没有父控件) ID:获取或设置分配给服务器控件的编程标识符.分配给控件的编程标识符. (可写) 设置服务器控件上的此属性可提供对服务器控件的属性.事件和方法的编程访问.Web 开发 ...

  8. 深入理解java虚拟机---垃圾收集器和分配策略-1

    博文重点: 学习目标:哪些内存需要回收 什么时候回收    如何回收 在基于概念讨论的模型中,主要对Java堆和方法区进行讨论. why?:一个接口中的多个实现类需要的内存可能不一样,一个方法中的多个 ...

  9. 迅为嵌入式4412平台兼容3G/4G模块的安卓开发板

    安卓开发板特点说明: 1. 配备16G固态硬盘EMMC存储 2. 64位双通道2GB内存 三星S5M8767电源管理 板载高精度GPS模块 CAN,RS-485等工业接口 板载WIFI蓝牙模块,陀螺仪 ...

  10. 5-Java-C(调和级数)

    题目描述: 1/1 + 1/2 + 1/3 + 1/4 + ... 在数学上称为调和级数. 它是发散的,也就是说,只要加上足够多的项,就可以得到任意大的数字. 但是,它发散的很慢: 前1项和达到 1. ...