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. #pragma pack 在BITMAP结构体定义中的使用

    BITMAP位图文件主要分为如下3个部分: 块名称 对应Windows结构体定义 大小(Byte) 文件信息头 BITMAPFILEHEADER 14 位图信息头 BITMAPINFOHEADER 4 ...

  2. 10-30SQLserver基础--(备份和还原、分离和附加数据库)、语句查询操作

    一.数据库是一个大容量的存储数据的仓库,为了保证数据完整性,防止一些数据的意外丢失等情况,需要对数据进行备份和还原. 备份数据不影响数据库的正常运行. 1.备份.还原数据库 首先对数据库进行备份,操作 ...

  3. 对数组名取地址 a[ ],&a

    C语言规定,数组名代表数组的首地址,也就是第0号元素的地址.所以a==&a[0] 但对数组名取地址时却要注意了,在理解“对数组名取地址”这一表达式的含义时一定要记住:数组名是“数组”这种变量的 ...

  4. centos7部署func

    Func(Fedora Unitied Network Controller)是红帽公司以Fedora平台构建的统一网络控制器,是为解决集群管理.监控问题而设计开发的系统管理基础框架.它是一个能有效简 ...

  5. 一个小错误,在for循环中,每次repaint()的时候,记得先把frame涂成白色的。等于擦掉原来的痕迹·。

    import java.awt.*; import java.awt.event.*; import javax.swing.*; public class Animate { int x=1; in ...

  6. 283E&EZOJ #89 Cow Tennis Tournament

    传送门 分析 我们考虑用所有的情况减去不合法的情况 不难想出所有情况为$C_n^3$ 于是我们考虑不合法的情况 我们知道对于一个不合法的三元组$(a,b,c)$一定是修改后$a<b,b>c ...

  7. ZROI2018提高day3t1

    传送门 分析 我们可以用贪心的思想.对于所有并没有指明关系的数一定是将小的放在前面.于是我们按顺序在每一个已经指明大小顺序的数前面插入所有比它小且没有指明关系的数.详见代码. 代码 #include& ...

  8. Hive安装及配置

    第一步:下载hive并解压 tar zxvf hive-0.8.1-bin.tar.gz 重命名: mv hive-0.8.1-bin hive 给权限:chown hadoop:hadoop hiv ...

  9. hadoop运行故障问题解决1——datanode节点启动后自动关闭

    ERROR org.apache.hadoop.hdfs.server.datanode.DataNode: java.io.IOException: Incompatible namespaceID ...

  10. Ubuntu16安装GTK+2.0教程

    Step 1 修改清华源(修改完可提高下载速度) 先运行 sudo gedit /etc/apt/sources.list 替换文本内容,保存,退出. # 默认注释了源码镜像以提高 apt updat ...