题目背景

数据规模和spoj上有所不同

题目描述

给定一棵n个节点的树,有两个操作:

  • CHANGE i ti 把第i条边的边权变成ti

  • QUERY a b 输出从a到b的路径中最大的边权,当a=b的时候,输出0

输入输出格式

输入格式:

第一行输入一个n,表示节点个数

第二行到第n行每行输入三个数,ui,vi,wi,分别表示 ui,vi有一条边,边权是wi

第n+1行开始,一共有不定数量行,每一行分别有以下三种可能

CHANGE,QUERY同题意所述

DONE表示输入结束

输出格式:

对于每个QUERY操作,输出一个数,表示a b之间边权最大值

输入样例:

3
1 2 1
2 3 2
QUERY 1 2
CHANGE 1 3
QUERY 1 2
DONE

输出样例:

1
3

解:

本题相较于洛谷P1505相比,操作少了许多。但是,两者单点修改有区别。此题要求修改第i条边,所以要开一个数组记录边所指向的点,而且注意,由于之前建的是双向边,所以记时i要除以二,修改时修改id[back[x]].

代码:

#include<cstdio>
#include<iostream>
#include<cstring>
#include<string>
#define MAXN 200010
#define inf 0x7fffffff
using namespace std;
struct node{
int nxt,to;
}e[MAXN<<1];
int head[MAXN],son[MAXN],top[MAXN],dep[MAXN];
int n,m,siz[MAXN],f[MAXN],a[MAXN],val[MAXN],xh;
int cnt,tot,id[MAXN],rk[MAXN],dt,rt,back[MAXN];
inline void swap(int &x,int &y){x^=y^=x^=y;}
char s[10];
inline int max_(int a,int b){return a>b?a:b;}
inline int min_(int a,int b){return a<b?a:b;}
inline int read(){
int s=0,w=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')w=-1;
ch=getchar();
}while(ch>='0'&&ch<='9'){
s=(s<<1)+(s<<3)+(ch^48);
ch=getchar();
}return s*w;
}
struct Node{
int ls,rs,sum,tag,maxn,minn,l,r;
}tr[MAXN<<2];
inline void add(int x,int y,int w){
e[++tot].to=y;
e[tot].nxt=head[x];
head[x]=tot;
a[tot]=w;
}void dfs1(int u){
siz[u]=1;
for(int i=head[u];i;i=e[i].nxt){
int v=e[i].to;
if(v==f[u])continue;
if(i%2==0)back[i/2]=v;
else back[i/2+1]=v;
f[v]=u;
val[v]=a[i];
dep[v]=dep[u]+1;
dfs1(v);
siz[u]=siz[v]+1;
if(siz[son[u]]<siz[v])son[u]=v;
}
}void dfs2(int u,int t){
top[u]=t;
rk[id[u]=++dt]=u;
if(!son[u])return;
dfs2(son[u],t);
for(int i=head[u];i;i=e[i].nxt){
int v=e[i].to;
if(v!=f[u]&&v!=son[u])dfs2(v,v);
}
}
#define lc tr[x].ls
#define rc tr[x].rs
inline void pushup(int x){
//tr[x].sum=tr[lc].sum+tr[rc].sum;
tr[x].maxn=max_(tr[lc].maxn,tr[rc].maxn);
//tr[x].minn=min_(tr[lc].minn,tr[rc].minn);
}
inline void pushdown(int x){
if(tr[x].tag){
tr[lc].sum=-tr[lc].sum,tr[lc].tag^=1;
tr[rc].sum=-tr[rc].sum,tr[rc].tag^=1;
int x1=tr[lc].maxn,y1=tr[lc].minn;
int x2=tr[rc].maxn,y2=tr[rc].minn;
tr[lc].maxn=-y1,tr[lc].minn=-x1;
tr[rc].maxn=-y2,tr[rc].minn=-x2;
tr[x].tag=0;
}
}
void build(int li,int ri,int &x){
x=++cnt;
tr[x].l=li;tr[x].r=ri;
if(li==ri){
tr[x].minn=tr[x].maxn=tr[x].sum=val[rk[li]];
return;
}int mid=(li+ri)>>1;
build(li,mid,lc);
build(mid+1,ri,rc);
pushup(x);
}
void change(int x,int val,int cur){
if(tr[x].l==tr[x].r){
tr[x].sum=tr[x].maxn=tr[x].minn=val;
return;
}//pushdown(x);
int mid=(tr[x].l+tr[x].r)>>1;
if(cur<=mid)change(lc,val,cur);
else change(rc,val,cur);
pushup(x);
}
void modify(int li,int ri,int x){
if(tr[x].l>=li&&tr[x].r<=ri){
tr[x].sum=-tr[x].sum,tr[x].tag^=1;
int x1=tr[x].maxn,y1=tr[x].minn;
tr[x].maxn=-y1,tr[x].minn=-x1;
return;
}pushdown(x);
int mid=(tr[x].l+tr[x].r)>>1;
if(li<=mid)modify(li,ri,lc);
if(mid<ri)modify(li,ri,rc);
pushup(x);
}
int query_s(int li,int ri,int x){
if(tr[x].l>ri||tr[x].r<li)return 0;
if(tr[x].l>=li&&tr[x].r<=ri)return tr[x].sum;
pushdown(x);
int mid=(tr[x].l+tr[x].r)>>1,ans=0;
ans=query_s(li,ri,lc)+query_s(li,ri,rc);
return ans;
}
int query_x(int li,int ri,int x){
if(tr[x].l>=li&&tr[x].r<=ri)return tr[x].maxn;
pushdown(x);
int mid=(tr[x].l+tr[x].r)>>1,ans=-inf;
if(li<=mid)ans=max_(ans,query_x(li,ri,lc));
if(mid<ri)ans=max_(ans,query_x(li,ri,rc));
return ans;
}
int query_n(int li,int ri,int x){
if(tr[x].l>=li&&tr[x].r<=ri){return tr[x].minn;}
pushdown(x);int mid=(tr[x].l+tr[x].r)>>1,ans=inf;
if(li<=mid)ans=min_(ans,query_n(li,ri,lc));
if(mid<ri)ans=min_(ans,query_n(li,ri,rc));
return ans;
}
void Segment_change(int x,int y){
int fx=top[x],fy=top[y];
while(fx!=fy){
if(dep[fx]<dep[fy])swap(x,y),swap(fx,fy);
modify(id[fx],id[x],rt);
x=f[fx],fx=top[x];
}if(id[x]>id[y])swap(x,y);
modify(id[x]+1,id[y],rt);
}
int query(int x,int y,int ck){//ck 0sum 1max 2min
int fx=top[x],fy=top[y],ans;
if(ck==0)ans=0;else if(ck==1)ans=-inf;else ans=inf;
while(fx!=fy){
if(dep[fx]<dep[fy])swap(x,y),swap(fx,fy);
if(ck==0)ans+=query_s(id[fx],id[x],rt);
else if(ck==1)ans=max_(ans,query_x(id[fx],id[x],rt));
else if(ck==2)ans=min_(ans,query_n(id[fx],id[x],rt));
x=f[fx],fx=top[x];
}if(id[x]>id[y])swap(x,y);
if(ck==0)ans+=query_s(id[x]+1,id[y],rt);
else if(ck==1)ans=max_(ans,query_x(id[x]+1,id[y],rt));
else if(ck==2)ans=min_(ans,query_n(id[x]+1,id[y],rt));
return ans;
}
int main(){dep[0]=1;
n=read();
for(register int i=1;i<n;++i){
int u=read(),v=read(),w=read();
add(u,v,w);add(v,u,w);
}dfs1(1);
dfs2(1,1);
build(1,n,rt);
while(1){
scanf("%s",s);
if(s[0]=='D')break;
int x=read(),y=read();
if(s[0]=='C')change(rt,y,id[back[x]]);
else if(s[0]=='Q'){
if(x==y)printf("0\n");
else printf("%d\n",query(x,y,1));
}
}
return 0;
}

感谢fsq dalao指教。

QTree1 【题解】的更多相关文章

  1. 【luogu P4114 Qtree1】 题解

    题目链接:https://www.luogu.org/problemnew/show/P4114 1.把边权转化到点权:选取连接这条边的两个点中较深的一个. 2.查询点到点之间的边权时,要从seg[x ...

  2. QTREE系列题解

    打了快一星期的qtree终于打完了- - (其实还有两题改不出来弃疗了QAQ) orz神AK一星期前就虐完QTREE 避免忘记还是简单写下题解吧0 0 QTREE1 题意: 给出一颗带边权树 一个操作 ...

  3. 2016 华南师大ACM校赛 SCNUCPC 非官方题解

    我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...

  4. noip2016十连测题解

    以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...

  5. BZOJ-2561-最小生成树 题解(最小割)

    2561: 最小生成树(题解) Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1628  Solved: 786 传送门:http://www.lyd ...

  6. Codeforces Round #353 (Div. 2) ABCDE 题解 python

    Problems     # Name     A Infinite Sequence standard input/output 1 s, 256 MB    x3509 B Restoring P ...

  7. 哈尔滨理工大学ACM全国邀请赛(网络同步赛)题解

    题目链接 提交连接:http://acm-software.hrbust.edu.cn/problemset.php?page=5 1470-1482 只做出来四道比较水的题目,还需要加强中等题的训练 ...

  8. 2016ACM青岛区域赛题解

    A.Relic Discovery_hdu5982 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Jav ...

  9. poj1399 hoj1037 Direct Visibility 题解 (宽搜)

    http://poj.org/problem?id=1399 http://acm.hit.edu.cn/hoj/problem/view?id=1037 题意: 在一个最多200*200的minec ...

随机推荐

  1. node.js的安装及其相关环境变量的配置

    笔者最近一直重置电脑,本来想换台mac,想了想还是加下配置吧. 于是慢慢的一直会去安装node 接下来进入教程环节 一.NodeJS下载 1.下载NodeJS安装包下载地址:NodeJS下载 2.开始 ...

  2. Unity3d启动事件 - InitializeOnLoad

    监听Unity3d启动事件 - InitializeOnLoad http://blog.csdn.net/huutu/article/details/42318499 Unity 监听第一次进入播放 ...

  3. 条件竞争(race condition)

    条件竞争漏洞是一种服务器端的漏洞,由于服务器端在处理不同用户的请求时是并发进行的,因此,如果并发处理不当或相关操作逻辑顺序设计的不合理时,将会导致此类问题的发生. 参考了一些资料,发现一个比较能说明问 ...

  4. .net core中使用jwt进行认证

    JSON Web Token(JWT)是一个开放标准(RFC 7519),它定义了一种紧凑且自包含的方式,用于在各方之间作为JSON对象安全地传输信息.由于此信息是经过数字签名的,因此可以被验证和信任 ...

  5. deepin20 安装英伟达闭源驱动

    第一步.安装深度的"显卡驱动器" 在deepin v20 中默认没有显卡驱动管理器,需要命令行安装,命令如下(刚开始一直出错,当我第一次打开应用商店,就可以安装了,好神奇): su ...

  6. 百度网盘,实现免费不限速,10M/S?

    前段时间,各大消息都说百度网盘实现了免费和不限速的『提速模式』,可以达到10M/S,于是我带着好奇想要进行测试一下,探一探真假,毕竟只有自己动手实践才知道真理,结果,辜负众望,一向对用户限速还限制上传 ...

  7. 用Maven给一个Maven工程打包,使用阿里云镜像解决mvn clean package出错的问题,使用plugin解决没有主清单属性的问题

    本来在STS里做了一个极简Maven工程,内中只有一个Main方法的Java类,然后用新装的Maven3.6.3给它打包. 结果,Maven罢工,输出如下: C:\personal\programs\ ...

  8. leetcode刷题-62不同路径

    题目 一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为“Start” ). 机器人每次只能向下或者向右移动一步.机器人试图达到网格的右下角(在下图中标记为“Finish”). 问总 ...

  9. leetcode刷题-39组合总和

    题目 给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合. candidates 中的数字可以无限制重 ...

  10. Linux:安装php

    一.环境准备(lamp环境:linux+apache+php+mysql) 1.安装php之前,首先要检查一下相关lib库 rpm -qa  zlib libxml libjpeg freetype ...