题目背景

数据规模和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. jdk1.8 新增工具类

    目录 optional 时间API Instant localDateTime LocalDate LocalTime Duration TemporalAdjuster DateTimeFormat ...

  2. Arbitrary-Oriented Object Detection with Circular Smooth Label(ECCV2020,旋转目标检测)

    论文链接:https://arxiv.org/abs/2003.05597 code:https://github.com/Thinklab-SJTU/CSL_RetinaNet_Tensorflow ...

  3. js error 错误处理

    (new) Error([message[, fileName[,lineNumber]]]) 单独定义Error()错误,函数继续进行 当像函数一样使用 Error 时 -- 如果没有 new,它将 ...

  4. leetcode刷题-78子集

    题目 给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集). 说明:解集不能包含重复的子集. 示例: 输入: nums = [1,2,3]输出:[ [3],  [1],  [2] ...

  5. TIKTOK 美国制裁

    今天在B站上看了沈教授和李自然说关于TIKTOK对于美国的声明采取的做法的一些看法.其实对于他们的看法,我觉得没有对错之分.正像两个新发的观点,在没有得到历史的验证前,谁也不会承认谁错了.更多的是两个 ...

  6. memcached缓存:安装和清缓存

    一.安装步骤: 1.将工具一直解压,解压到最底层的exe目录

  7. 循环删除list的方法

    错误的方法: 正确的方法:

  8. Unit5:广播

    静态广播 1.定义 public class TestBroadCast extends BroadcastReceiver { @Override public void onReceive(Con ...

  9. VirtualBox中安装的CentOS开启SSH并设置访问外网

    1.全局设置NAT网络 打开VirtualBox->管理->全局设定 网络->添加按钮->添加一个NAT网络(使用默认的就行,不用改动) 2.设置用来本机于VirtualBox ...

  10. 复习 | 彻底弄懂Flexbox之Demo篇

    flexbox之前有接触,写项目时也用过,但也只是简单的,对其也是似懂非懂,所以今天下定决心把这个再学一遍,因为似懂非懂就是不懂 本文主要是的demo演示,想看flexbox语法 请移步flexbox ...