当前位置: 首页 > news >正文

1036. [ZJOI2008]树的统计【树链剖分】

Description

  一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w。我们将以下面的形式来要求你对这棵树完成
一些操作: I. CHANGE u t : 把结点u的权值改为t II. QMAX u v: 询问从点u到点v的路径上的节点的最大权值 I
II. QSUM u v: 询问从点u到点v的路径上的节点的权值和 注意:从点u到点v的路径上的节点包括u和v本身

Input

  输入的第一行为一个整数n,表示节点的个数。接下来n – 1行,每行2个整数a和b,表示节点a和节点b之间有
一条边相连。接下来n行,每行一个整数,第i行的整数wi表示节点i的权值。接下来1行,为一个整数q,表示操作
的总数。接下来q行,每行一个操作,以“CHANGE u t”或者“QMAX u v”或者“QSUM u v”的形式给出。
对于100%的数据,保证1<=n<=30000,0<=q<=200000;中途操作中保证每个节点的权值w在-30000到30000之间。

Output

  对于每个“QMAX”或者“QSUM”的操作,每行输出一个整数表示要求输出的结果。

Sample Input

4
1 2
2 3
4 1
4 2 1 3
12
QMAX 3 4
QMAX 3 3
QMAX 3 2
QMAX 2 3
QSUM 3 4
QSUM 2 1
CHANGE 1 5
QMAX 3 4
CHANGE 3 6
QMAX 3 4
QMAX 2 4
QSUM 3 4

Sample Output

4
1
2
2
10
6
5
6
5
16

树链剖分模板

 

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstdlib>
  4 #include<cstring>
  5 using namespace std;
  6 
  7 int head[30001],num_edge;
  8 int Father[30001],Weight[30001];
  9 int Son[30001],Top[30001];
 10 int T_NUM[30001],a[30001];
 11 int Depth[30001];
 12 int sum,n,INF,ans;
 13 int TREE[30001];
 14 char st[101];
 15 struct node
 16 {
 17     int to,next;
 18 } edge[60005];
 19 struct node1
 20 {
 21     int max,sum;
 22 } Segt[120001];
 23 void add(int u,int v)
 24 {
 25     edge[++num_edge].to=v;
 26     edge[num_edge].next=head[u];
 27     head[u]=num_edge;
 28 }
 29 void dfs1(int x)
 30 {
 31     Weight[x]=1;
 32     Depth[x]=Depth[Father[x]]+1;
 33     for (int i=head[x]; i!=0; i=edge[i].next)
 34         if (edge[i].to!=Father[x])
 35         {
 36             Father[edge[i].to]=x;
 37             dfs1(edge[i].to);
 38             Weight[x]+=Weight[edge[i].to];
 39             if (Son[x]==0 || Weight[edge[i].to]>Weight[Son[x]])
 40                 Son[x]=edge[i].to;
 41         }
 42 }
 43 
 44 void dfs2(int x,int tp)
 45 {
 46     T_NUM[x]=++sum;
 47     TREE[sum]=a[x];
 48     Top[x]=tp;
 49     if (Son[x]!=0)
 50         dfs2(Son[x],tp);
 51     for (int i=head[x]; i!=0; i=edge[i].next)
 52         if (edge[i].to!=Son[x] && edge[i].to!=Father[x])
 53             dfs2(edge[i].to,edge[i].to);
 54 }
 55 
 56 void Build(int node,int l,int r,int a[])
 57 {
 58     if (l==r)
 59         Segt[node].max=Segt[node].sum=a[l];
 60     else
 61     {
 62         int mid=(l+r)/2;
 63         Build(node*2,l,mid,a);
 64         Build(node*2+1,mid+1,r,a);
 65         Segt[node].max=max(Segt[node*2].max,Segt[node*2+1].max);
 66         Segt[node].sum=Segt[node*2].sum+Segt[node*2+1].sum;
 67     }
 68 }
 69 
 70 void Update(int node,int l,int r,int x,int k)
 71 {
 72     if (l==r)
 73         Segt[node].max=Segt[node].sum=k;
 74     else
 75     {
 76         mid=(l+r)/2;
 77         (x<=mid)
 78         date(node*2,l,mid,x,k);
 79         else
 80             Update(node*2+1,mid+1,r,x,k);
 81         Segt[node].max=max(Segt[node*2].max,Segt[node*2+1].max);
 82         Segt[node].sum=Segt[node*2].sum+Segt[node*2+1].sum;
 83     }
 84 }
 85 
 86 int QueryMax(int node,int l,int r,int l1,int r1)
 87 {
 88     if (r<l1 || l>r1)
 89         return -INF;
 90     if (l1<=l && r<=r1)
 91         return Segt[node].max;
 92     int mid=(l+r)/2;
 93     return max(QueryMax(node*2,l,mid,l1,r1),
 94                QueryMax(node*2+1,mid+1,r,l1,r1));
 95 }
 96 
 97 int QuerySum(int node,int l,int r,int l1,int r1)
 98 {
 99     if (r<l1 || l>r1)
100         return 0;
101     if (l1<=l && r<=r1)
102         return Segt[node].sum;
103     int mid=(l+r)/2;
104     return QuerySum(node*2,l,mid,l1,r1)+
105            QuerySum(node*2+1,mid+1,r,l1,r1);
106 }
107 
108 int GetSum(int x,int y)
109 {
110     int fx,fy;
111     memset(&ans,0,sizeof(ans));
112     fx=Top[x];
113     fy=Top[y];
114     while (fx!=fy)
115     {
116         if (Depth[fx]<Depth[fy])
117             swap(fx,fy),swap(x,y);
118         ans+=QuerySum(1,1,n,T_NUM[fx],T_NUM[x]);
119         x=Father[fx],fx=Top[x];
120     }
121     if (Depth[x]>Depth[y]) swap(x,y);
122     return ans+=QuerySum(1,1,n,T_NUM[x],T_NUM[y]);
123 }
124 
125 int GetMax(int x,int y)
126 {
127     int fy,fx;
128     memset(&ans,-0x7f,sizeof(ans));
129     fx=Top[x];
130     fy=Top[y];
131     while (fx!=fy)
132     {
133         if (Depth[fx]<Depth[fy])
134             swap(fx,fy),swap(x,y);
135         ans=max(ans,QueryMax(1,1,n,T_NUM[fx],T_NUM[x]));
136         x=Father[fx],fx=Top[x];
137     }
138     if (Depth[x]>Depth[y]) swap(x,y);
139     return max(ans,QueryMax(1,1,n,T_NUM[x],T_NUM[y]));
140 }
141 
142 int main()
143 {
144     int i,u,v,l,m,x,y;
145     memset(&INF,0x7f,sizeof(INF));
146     scanf("%d",&n);
147     for (i=1; i<=n-1; ++i)
148     {
149         scanf("%d%d",&u,&v);
150         add(u,v);
151         add(v,u);
152     }
153     for (int i=1; i<=n; ++i)
154         scanf("%d",&a[i]);
155     Depth[1]=1;
156     dfs1(1);
157     dfs2(1,1);//两边预处理
158     Build(1,1,n,TREE);//TREE数组保存用来建线段树的区间
159     scanf("%d",&m);
160     for (int i=1; i<=m; ++i)
161     {
162         scanf("%s%d%d",&st,&x,&y);
163         if (st[1]=='H')
164             Update(1,1,n,T_NUM[x],y);
165         if (st[1]=='M')
166             printf("%d\n",GetMax(x,y));
167         if (st[1]=='S')
168             printf("%d\n",GetSum(x,y));
169     }
170 }

转载于:https://www.cnblogs.com/refun/p/8678456.html

相关文章:

  • Koa2 之文件上传下载
  • BZOJ1010:[HNOI2008]玩具装箱TOY(斜率优化DP)
  • 黑客基础之 DOS命令3
  • postgreSQL中如何实现group_concat
  • Linux系统获取命令帮助方法及简单命令介绍
  • ★ prototype、__proto__ 详解
  • 大数据生态圈的一致性
  • Java 8 并发篇 - 冷静分析 Synchronized(上)
  • 运维面试题
  • react-router了解一下
  • 狼叔:Node全栈为前端带来更多可能
  • 滚动条
  • 精通比特币系列---挖矿与共识
  • c:if test=/c:if如何判断空(使用例子)
  • 企业做营销型网站有什么特点
  • “Material Design”设计规范在 ComponentOne For WinForm 的全新尝试!
  • ➹使用webpack配置多页面应用(MPA)
  • JavaScript标准库系列——Math对象和Date对象(二)
  • JS数组方法汇总
  • Redis字符串类型内部编码剖析
  • TiDB 源码阅读系列文章(十)Chunk 和执行框架简介
  • Tornado学习笔记(1)
  • 基于阿里云移动推送的移动应用推送模式最佳实践
  • 技术胖1-4季视频复习— (看视频笔记)
  • 译米田引理
  • 正则学习笔记
  • 扩展资源服务器解决oauth2 性能瓶颈
  • # 学号 2017-2018-20172309 《程序设计与数据结构》实验三报告
  • #我与Java虚拟机的故事#连载01:人在JVM,身不由己
  • (5)STL算法之复制
  • (pojstep1.1.1)poj 1298(直叙式模拟)
  • (Redis使用系列) SpirngBoot中关于Redis的值的各种方式的存储与取出 三
  • (二)windows配置JDK环境
  • (仿QQ聊天消息列表加载)wp7 listbox 列表项逐一加载的一种实现方式,以及加入渐显动画...
  • (离散数学)逻辑连接词
  • (论文阅读31/100)Stacked hourglass networks for human pose estimation
  • (续)使用Django搭建一个完整的项目(Centos7+Nginx)
  • (一)插入排序
  • (转)linux下的时间函数使用
  • (转)总结使用Unity 3D优化游戏运行性能的经验
  • (转载)利用webkit抓取动态网页和链接
  • (转载)虚函数剖析
  • .java 9 找不到符号_java找不到符号
  • .java 指数平滑_转载:二次指数平滑法求预测值的Java代码
  • .Net Core webapi RestFul 统一接口数据返回格式
  • .NET delegate 委托 、 Event 事件,接口回调
  • .net 无限分类
  • .NET 指南:抽象化实现的基类
  • .NET开源全面方便的第三方登录组件集合 - MrHuo.OAuth
  • .net生成的类,跨工程调用显示注释
  • .NET下ASPX编程的几个小问题
  • @Controller和@RestController的区别?
  • [APIO2015]巴厘岛的雕塑
  • [AutoSar]BSW_Com02 PDU详解
  • [C#]使用DlibDotNet人脸检测人脸68特征点识别人脸5特征点识别人脸对齐人脸比对FaceMesh