P4114 Qtree1

题目描述

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

  • CHANGE i ti 把第i条边的边权变成ti
  • QUERY a b 输出从a到b的路径中最大的边权,当a=b的时候,输出0

码农题。

话说我码得变快了啊,虽然跟顾z吹45分钟码完Qtree没有完成,不过总共用了55分钟还是不长的嘿嘿。

code:

#include <iostream>
#include <cstdio> #define ls(o) o<<1
#define rs(o) o<<1|1 #define int long long using namespace std; const int wx=500017; int head[wx],dfn[wx],size[wx],f[wx][23],dis[wx][23],dep[wx];
int son[wx],a[wx],top[wx],tid[wx];
int n,num,tot;
char opt[17]; inline int read(){
int sum=0,f=1; char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();}
while(ch>='0'&&ch<='9'){sum=(sum<<1)+(sum<<3)+ch-'0'; ch=getchar();}
return sum*f;
} /*~~~~~~~~~~~~~~~~~~~ * ~~~~~~~~~~~~~~~~~~~~*/ struct e{
int nxt,to,dis;
}edge[wx*2]; void add(int from,int to,int dis){
edge[++num].nxt=head[from];
edge[num].to=to;
edge[num].dis=dis;
head[from]=num;
} int first_dfs(int u,int fa){
size[u]=1; int maxson=-1; dep[u]=dep[fa]+1;
dis[u][0]=a[u];
f[u][0]=fa;
for(int i=head[u];i;i=edge[i].nxt){
int v=edge[i].to;
if(v==fa)continue;
a[v]=edge[i].dis;
first_dfs(v,u);
size[u]+=size[v];
if(size[v]>maxson){
maxson=size[v]; son[u]=v;
}
}
} int second_dfs(int u,int topf){
dfn[u]=++tot; top[u]=topf; tid[tot]=u;
if(son[u])second_dfs(son[u],topf);
for(int i=head[u];i;i=edge[i].nxt){
int v=edge[i].to;
if(dfn[v]||v==f[u][0])continue;
second_dfs(v,v);
}
}
/*~~~~~~~~~~~~~~~~~~~ * ~~~~~~~~~~~~~~~~~~~~*/ /*~~~~~~~~~~~~~~~~~ SGT~~~~~~~~~~~~~~~~~~~~~*/ struct SGT{
int l,r,tag,ma;
#define tag(o) t[o].tag
#define ma(o) t[o].ma
}t[wx*4]; void up(int o){
ma(o)=max(ma(ls(o)),ma(rs(o)));
} void down(int o){
if(tag(o)!=-1){
ma(ls(o))=tag(o); ma(rs(o))=tag(o);
tag(ls(o))=tag(o); tag(rs(o))=tag(o);
tag(o)=-1;
}
} void build(int o,int l,int r){
t[o].l=l; t[o].r=r; tag(o)=-1;
if(l==r){ma(o)=a[tid[l]]; return ;}
int mid=t[o].l+t[o].r>>1;
if(l<=mid)build(ls(o),l,mid);
if(r>mid)build(rs(o),mid+1,r);
up(o);
} void update_SGT(int o,int l,int r,int k){
if(l<=t[o].l&&t[o].r<=r){
ma(o)=k; tag(o)=k;
return ;
}
down(o);
int mid=t[o].l+t[o].r>>1;
if(l<=mid)update_SGT(ls(o),l,r,k);
if(r>mid)update_SGT(rs(o),l,r,k);
up(o);
} int query_SGT(int o,int l,int r){
if(l>r)return 0;
if(l<=t[o].l&&t[o].r<=r){
return ma(o);
}
down(o); int maxn=-1;
int mid=t[o].l+t[o].r>>1;
if(l<=mid)maxn=max(maxn,query_SGT(ls(o),l,r));
if(r>mid)maxn=max(maxn,query_SGT(rs(o),l,r));
return maxn;
} /*~~~~~~~~~~~~~~~~~ SGT~~~~~~~~~~~~~~~~~~~~~*/ /*~~~~~~~~~~~~~~~~~ LCA~~~~~~~~~~~~~~~~~~~~~*/ void pre(){
for(int j=1;j<=21;j++)for(int i=1;i<=n;i++)f[i][j]=f[f[i][j-1]][j-1],dis[i][j]=max(dis[f[i][j-1]][j-1],dis[i][j-1]);
} int find(int x,int y){
if(dep[x]<dep[y])swap(x,y);
int re=-1;
for(int i=21;i>=0;i--){
if(dep[f[x][i]]>=dep[y]){
re=max(re,dis[x][i]);
x=f[x][i];
}
}
if(x==y)return re;
for(int i=21;i>=0;i--){
if(f[x][i]!=f[y][i]){
re=max(re,max(dis[x][i],dis[y][i]));
x=f[x][i]; y=f[y][i];
}
}
return max(re,max(dis[x][0],dis[y][0]));
} int LCA(int x,int y){
if(dep[x]<dep[y])swap(x,y);
for(int i=21;i>=0;i--){
if(dep[f[x][i]]>=dep[y]){
x=f[x][i];
}
}
if(x==y)return x;
for(int i=21;i>=0;i--){
if(f[x][i]!=f[y][i]){
x=f[x][i]; y=f[y][i];
}
}
return f[x][0];
} /*~~~~~~~~~~~~~~~~~ LCA~~~~~~~~~~~~~~~~~~~~~*/ /*~~~~~~~~~~~~~~~~~ shu pou~~~~~~~~~~~~~~~~~*/ void update(int x,int y,int k){
int fx=top[x]; int fy=top[y];
while(fx!=fy){
if(dep[fx]>=dep[fy])update_SGT(1,dfn[fx],dfn[x],k),x=f[fx][0];
else update_SGT(1,dfn[fy],dfn[y],k),y=f[fy][0];
fx=top[x]; fy=top[y];
}
if(dfn[x]>dfn[y])swap(x,y);
update_SGT(1,dfn[x],dfn[y],k);
} int query(int x,int y){
int fx=top[x]; int fy=top[y]; int re=-1;
while(fx!=fy){
if(dep[fx]>=dep[fy])re=max(re,query_SGT(1,dfn[fx],dfn[x])),x=f[fx][0];
else re=max(re,query_SGT(1,dfn[fy],dfn[y])),y=f[fy][0];
fx=top[x]; fy=top[y];
}
if(dfn[x]>dfn[y])swap(x,y);
re=max(re,query_SGT(1,dfn[x],dfn[y]));
return re;
} /*~~~~~~~~~~~~~~~~~ shu pou~~~~~~~~~~~~~~~~~*/
signed main(){
n=read();
for(int i=1;i<n;i++){
int x,y,z;
x=read(); y=read(); z=read();
add(x,y,z); add(y,x,z);
}
first_dfs(1,0); second_dfs(1,1); build(1,1,n); pre();
while(1){
scanf("%s",opt+1);
if(opt[1]=='D')break;
if(opt[1]=='Q'){
int x,y;
x=read(); y=read();
if(x==y)puts("0");
else{
int lca=LCA(x,y);
int tmp=query_SGT(1,dfn[lca],dfn[lca]);
update_SGT(1,dfn[lca],dfn[lca],-521);
printf("%lld\n",query(x,y));
update_SGT(1,dfn[lca],dfn[lca],tmp);
}
}
if(opt[1]=='C'){
int x,y;
x=read(); y=read();
int x1=edge[x*2-1].to;
int x2=edge[x*2].to;
if(dep[x1]>dep[x2])x=x1;
else x=x2;
update(x,x,y);
}
}
return 0;
} /* 3
1 2 1
2 3 2
QUERY 1 2
CHANGE 1 3
QUERY 1 2
DONE */

树链剖分【洛谷P4114】 Qtree1的更多相关文章

  1. AC日记——【模板】树链剖分 洛谷 P3384

    题目描述 如题,已知一棵包含N个结点的树(连通且无环),每个节点上包含一个数值,需要支持以下操作: 操作1: 格式: 1 x y z 表示将树从x到y结点最短路径上所有节点的值都加上z 操作2: 格式 ...

  2. 洛谷 P4114 Qtree1 树链剖分

    目录 题面 题目链接 题目描述 输入输出格式 输入格式: 输出格式: 输入输出样例 输入样例: 输出样例: 说明 说明 思路 Change Query AC代码 总结 题面 题目链接 P4114 Qt ...

  3. 洛谷P4114 Qtree1

    题目描述 给定一棵\(n\)个节点的树,有两个操作: \(CHANGE\) \(i\) \(t_i\) 把第\(i\)条边的边权变成\(t_i\) \(QUERY\) \(a\) \(b\) 输出从\ ...

  4. 洛谷P4114 Qtree1(树链剖分+线段树)

    传送门 LCT秒天秒地用什么树剖 这题可以算是树剖的比较裸的题目了 把每一条边的权值下放到他两边的点中深度较深的那个 然后直接用树剖+线段树带进去乱搞就可以了 //minamoto #include& ...

  5. 洛谷 - P4114 - Qtree1 - 重链剖分

    https://www.luogu.org/problem/P4114 维护边权的话,用深度大的点表示这条边(可以遍历一边边询问两端深度,这样不需要修改dfs1,也可以在dfs1的时候向下走的同时把边 ...

  6. 洛谷 P4114 Qtree1

    Qtree系列都跟树有着莫大的联系,这道题当然也不例外 我是题面 读完题,我们大概就知道了,这道题非常简单,可以说是模板题.树剖+线段树轻松解决 直接看代码吧 #include<algorith ...

  7. 洛谷 P3384 【模板】树链剖分

    树链剖分 将一棵树的每个节点到它所有子节点中子树和(所包含的点的个数)最大的那个子节点的这条边标记为"重边". 将其他的边标记为"轻边". 若果一个非根节点的子 ...

  8. 树链剖分详解(洛谷模板 P3384)

    洛谷·[模板]树链剖分 写在前面 首先,在学树链剖分之前最好先把 LCA.树形DP.DFS序 这三个知识点学了 emm还有必备的 链式前向星.线段树 也要先学了. 如果这三个知识点没掌握好的话,树链剖 ...

  9. ⌈洛谷1505⌋⌈BZOJ2157⌋⌈国家集训队⌋旅游【树链剖分】

    题目链接 [洛谷] [BZOJ] 题目描述 Ray 乐忠于旅游,这次他来到了T 城.T 城是一个水上城市,一共有 N 个景点,有些景点之间会用一座桥连接.为了方便游客到达每个景点但又为了节约成本,T ...

  10. BZOJ2243 洛谷2486 [SDOI2011]染色 树链剖分

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ2243 题目传送门 - 洛谷2486 题意概括 一棵树,共n个节点. 让你支持以下两种操作,共m次操 ...

随机推荐

  1. 第十四章 Spring MVC的工作机制与设计模式(待续)

    Spring MVC的总体设计 Control设计 Model设计 View设计 框架设计的思考 设计模式解析之模版模式

  2. CentOS6.5安装完没有网络的解决办法

    昨天下了个CentOS 6.5 Minimal 版,在VMware 10下安装好了之后,发现上不了网,PING外网也PING不通. 在网上搜了一下,发现Linux安装好了之后,网卡默认是没有启动的,下 ...

  3. 部署和调优 2.2 squid反向代理

    配置反向代理 打开配置文件 vim /etc/squid/squid.conf 修改 http_port 改为 http_port 80 accel vhost vport 在它下面添加一段 cach ...

  4. Django的Model使用

    创建模型 使用Django的模型主要注意两个方面:字段的类型和方法的重写.这里用一个例子来说明,其中包含了常用的字段类型和如何重写方法. from django.db import models cl ...

  5. [Python Study Notes]行人检测

    # -------------------------------------------------------------- # @文件: 行人识别.py # @工程: blog # @时间: 2 ...

  6. 嵌入式Linux启动优化手记2&nbsp;U…

    参考一下 原文地址:U-boot优化">嵌入式Linux启动优化手记2 U-boot优化作者:ZhaoJunling 既然不能使用新的U-boot,那就优化一点是一点,慢慢干吧. 1. ...

  7. 框架之 hibernate之各种查询

    1. Hibernate的查询方式 2. Hibernate的查询策略 案例:使用Hibernate完成查询所有联系人功能 需求分析 1. 完成所有的联系人的查询 技术分析之Hibernate框架的查 ...

  8. Ros学习——C++发布器publisher和订阅器subscriber

    1.编写发布器 初始化 ROS 系统 在 ROS 网络内广播我们将要在 chatter 话题上发布 std_msgs/String 类型的消息 以每秒 10 次的频率在 chatter 上发布消息 在 ...

  9. wenfrom的简单控件和repeater控件

    简单控件 lable  转换成<span>标记 literal   空的  什么也没转换 Literal.Text=<script>alter('你好');</scrip ...

  10. mysql 5.7.11 源码安装

    mysql5.711安装 1.安装boost包下载地址http://sourceforge.net/projects/boost/files/boost/ 2.解压boost_1_59_0.tar.g ...