传送门:http://oj.cnuschool.org.cn/oj/home/problem.htm?problemID=979

WZJ的数据结构(六)
难度级别:D; 运行时间限制:1000ms; 运行空间限制:51200KB; 代码长度限制:2000000B
试题描述

给你一棵N个节点的无根树,边之间有权值。请你设计一个数据结构,进行以下两种操作:

1.修改:给你a、b,将第a条边的权值改为b。

2.询问:给你a、b,输出从a到b路径上的最大值、最小值与权值和,如果a=b,输出"error"。

输入
第一行为一个正整数N。
接下来N-1行为每一条边,每行3个正整数a,b,c,表示有一条从a到b权值为c的边(从1开始编号)。
第N+1行为一个正整数Q,表示Q次操作。
接下来Q行为每一次询问,每行3个正整数t,a,b,若t=1表示询问,t=0表示修改。
输出
对于每一次询问,输出三个正整数,即最大值、最小值与权值和,如果a=b,输出"error"。
输入示例
5 
1 2 4
1 4 5
3 4 6
2 5 7
4
1 1 5
1 2 5
0 1 2
1 1 5
输出示例
7 4 11
7 7 7
7 2 9
其他说明
1<=N,Q<=50000
1<=c<=1000
询问中的1<=a,b<=N
修改中的1<=a<=N-1,1<=b<=1000

题解:懒得写树链剖分了LCT走起

 #include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<queue>
#include<cstring>
#define PAU putchar(' ')
#define ENT putchar('\n')
using namespace std;
const int maxn=+,inf=-1u>>;
inline int read(){
int x=,sig=;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')sig=-;ch=getchar();}
while(isdigit(ch))x=*x+ch-'',ch=getchar();
return x*=sig;
}
inline void write(int x){
if(x==){putchar('');return;}if(x<)putchar('-'),x=-x;
int len=,buf[];while(x)buf[len++]=x%,x/=;
for(int i=len-;i>=;i--)putchar(buf[i]+'');return;
}
struct node {
int x,mi,mx,sm,set;bool rev;
node *ch[],*fa;
inline void add_rev_tag(){
swap(ch[],ch[]);rev^=;return;
}
inline void add_set_tag(int a){
x=set=a;
if(mi!=inf) mi=set;
if(mx!=-inf) mx=set;
}
inline void down(){
if(rev){
if(ch[]) ch[]->add_rev_tag();
if(ch[]) ch[]->add_rev_tag();
rev=;
}
if(set){
if(ch[]) ch[]->add_set_tag(set);
if(ch[]) ch[]->add_set_tag(set);
set=;
}
return;
}
inline void update(){
sm=x;mi=inf;mx=-inf;
if(ch[]) sm+=ch[]->sm,mi=min(mi,ch[]->mi),mx=max(mx,ch[]->mx);
if(ch[]) sm+=ch[]->sm,mi=min(mi,ch[]->mi),mx=max(mx,ch[]->mx);
if(!x) return;
mi=min(x,mi);
mx=max(x,mx);
return;
}
}lct[maxn];
inline int get_parent(node *x,node *&fa){return (fa=x->fa)?fa->ch[]==x?:fa->ch[]==x?:-:-;}
inline void rotate(node *x){
int t1,t2;
node *fa,*gfa;
t1=get_parent(x,fa);
t2=get_parent(fa,gfa);
if ((fa->ch[t1]=x->ch[t1^])) fa->ch[t1]->fa=fa;
x->ch[t1^]=fa;fa->fa=x;x->fa=gfa;
if (t2!=-) gfa->ch[t2]=x;
fa->update();return;
}
inline void pushdown(node *x){
static node *stack[maxn];
int cnt=;
while(){
stack[cnt++]=x;
node *fa=x->fa;
if (!fa || (fa->ch[]!=x && fa->ch[]!=x)) break;
x=fa;
}
while(cnt--) stack[cnt]->down();
return;
}
inline node * splay(node *x){
pushdown(x);
while(){
int t1,t2;
node *fa,*gfa;
t1=get_parent(x,fa);
if(t1==-) break;
t2=get_parent(fa,gfa);
if(t2==-){
rotate(x);break;
} else if (t1==t2){
rotate(fa);rotate(x);
} else{
rotate(x);rotate(x);
}
}
x->update();
return x;
}
inline node * access(node *x){
node *ret=NULL;
while (x) splay(x)->ch[]=ret,(ret=x)->update(),x=x->fa;
return ret;
}
inline void makeroot(int x){access(lct+x)->add_rev_tag();}
inline void link(int u,int v){
makeroot(u);splay(lct+u)->fa=lct+v;return;
}
int n,q;
int main(){
n=read();
int i;
int lim=n<<;
for(i=;i<=lim;i++) {
lct[i]=(node){,inf,-inf,,,};
}
for(i=;i<n;i++){
int u,v,w;
u=read();v=read();
link(u,i+n);link(v,i+n);lct[i+n].add_set_tag(read());
}
q=read();
int x,y,c;
while(q--){
c=read();x=read();y=read();
if(c==) makeroot(x+n),access(x+n+lct)->add_set_tag(y);
else{
if(x==y){puts("error");continue;}
makeroot(x);node*t=access(y+lct);
write(t->mx);PAU;write(t->mi);PAU;write(t->sm);ENT;
}
}
return ;
}

搜索

复制

COJ 1006 树上操作的更多相关文章

  1. 【BZOJ4034】[HAOI2015]树上操作 树链剖分+线段树

    [BZOJ4034][HAOI2015]树上操作 Description 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三种: 操作 1 :把某个节点 x 的点权增加 ...

  2. HAOI2015 树上操作

    HAOI2015 树上操作 题目描述 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个操作,分为三种:操作 1 :把某个节点 x 的点权增加 a .操作 2 :把某个节点 x 为根 ...

  3. bzoj千题计划242:bzoj4034: [HAOI2015]树上操作

    http://www.lydsy.com/JudgeOnline/problem.php?id=4034 dfs序,树链剖分 #include<cstdio> #include<io ...

  4. bzoj4034[HAOI2015]树上操作 树链剖分+线段树

    4034: [HAOI2015]树上操作 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 6163  Solved: 2025[Submit][Stat ...

  5. 树剖||树链剖分||线段树||BZOJ4034||Luogu3178||[HAOI2015]树上操作

    题面:P3178 [HAOI2015]树上操作 好像其他人都嫌这道题太容易了懒得讲,好吧那我讲. 题解:第一个操作和第二个操作本质上是一样的,所以可以合并.唯一值得讲的点就是:第二个操作要求把某个节点 ...

  6. P3178 [HAOI2015]树上操作

    P3178 [HAOI2015]树上操作 思路 板子嘛,其实我感觉树剖没啥脑子 就是debug 代码 #include <bits/stdc++.h> #define int long l ...

  7. bzoj 4034: [HAOI2015]树上操作 树链剖分+线段树

    4034: [HAOI2015]树上操作 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 4352  Solved: 1387[Submit][Stat ...

  8. bzoj 4034: [HAOI2015]树上操作 (树剖+线段树 子树操作)

    4034: [HAOI2015]树上操作 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 6779  Solved: 2275[Submit][Stat ...

  9. BZOJ.4034 [HAOI2015]树上操作 ( 点权树链剖分 线段树 )

    BZOJ.4034 [HAOI2015]树上操作 ( 点权树链剖分 线段树 ) 题意分析 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三种: 操作 1 :把某个节点 ...

随机推荐

  1. Android 网络技术HTTP

    1.XML3种解析方式(DOM.SAX.PULL) 在网络上传输数据时最常用的格式有两种,XML 和JSON 这里首先明白什么是SAX是一个用于处理XML事件驱动的"推"模型,优点 ...

  2. MySQL的字符编码体系(二)——传输数据编码

    MySQL的字符编码体系能够分成两部分:一部分是关于数据库server本身存储数据表时怎样管理字符数据的编码:还有一部分是关于client与数据库server数据传输怎样编码.上一篇MySQL的字符编 ...

  3. tomcat URL简写案例:模拟站点www.baidu.com的訪问

    tomcat URL简写案例:模拟站点  * 实际URL:http://www.baidu.com:8080/myweb/1.html  * 实际位置:F:\mywebapps\myweb\1.htm ...

  4. MySQL存储过程详解 mysql 存储过程(二)

    mysql存储过程详解 1.      存储过程简介 我们常用的操作数据库语言SQL语句在执行的时候需要要先编译,然后执行,而存储过程(Stored Procedure)是一组为了完成特定功能的SQL ...

  5. Python的基本配置

    Python是一个高层次的结合了解释性.编译性.互动性和面向对象的脚本语言. Python的设计具有很强的可读性,相比其他语言经常使用英文关键字,其他语言的一些标点符号,它具有比其他语言更有特色语法结 ...

  6. asp.net中Page.ClientScript.RegisterStartupScript用法小结(转)

    //ASP.NET后台页面跳转 Page.ClientScript.RegisterStartupScript(Page.GetType(), "", "<scri ...

  7. Android系统下的动态Dex加载与app速度优化

    1 问题 在Android系统中,一个App的所有代码都在一个Dex文件里面.Dex是一个类似Jar的存储了多有Java编译字节码的归档文件.因为Android系统使用Dalvik虚拟机,所以需要把 ...

  8. 关于android应用闪屏的几种情况

    1.主菜单进入某应用闪屏: 常见是一个空的activity作为launcher属性,实际上它什么事业没干,真正干事情的是从它通过intent启动的activity. 例子: public class ...

  9. Asp.net 事务处理

    事务处理是在数据处理时经常遇到的问题,经常用到的方法有以下三种总结整理如下:方法1:直接写入到sql 中在存储过程中使用 BEGIN TRANS, COMMIT TRANS, ROLLBACK TRA ...

  10. 你好,C++(10)这次的C++考试你过了没有?C++中表示逻辑判断的布尔数据类型

    3.4  布尔类型 在日常生活中,我们除了需要使用int类型的变量表示216路公交车:需要使用float类型的变量表示西红柿3.5元一斤,有时候还需要表示一种数据,那就是逻辑状态: “这次的C++考试 ...