ZJOI 2008 树上的统计

一树上有 n 个节点,编号分别为 1 到 n,每个节点都有一个权值 w。我们将以下面的形式来要求你对这棵树完成一些操作:

  1. CHANGE u t :把节点 u 权值改为t;
  2. QMAX u v :询问点 u 到点 v 路径上的节点的最大权值;
  3. QSUM u v :询问点 u 到点 v 路径上的节点的权值和。

注意:从点 u 到点 v 路径上的节点包括 u 和 v 本身。

输入格式

第一行为一个数 n,表示节点个数;

接下来 n-1 行,每行两个整数 a,b,表示节点 a与节点 b 之间有一条边相连;

接下来 n 行,每行一个整数,第 i 行的整数 wi​ 表示节点i 的权值;

接下来一行,为一个整数 q ,表示操作总数;

接下来 q 行,每行一个操作,以 CHANGE u t 或 QMAX u v 或 QSUM u v的形式给出。

输出格式

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

样例

样例输入

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

样例输出

4
1
2
2
10
6
5
6
5
16

数据范围与提示

对于 100% 的数据,有1≤n≤3×10^4,0≤q≤2×10^5。中途操作中保证每个节点的权值 w 在 −30000 至 30000 之间。

_______________________________________________________________________________________

很简单的树剖,好久没有写了,第一次写的不知道哪里错了,还是写了第二次!

_______________________________________________________________________________________

  1 #include<bits/stdc++.h>
2 using namespace std;
3 typedef long long ll;
4 const ll maxn=30020;
5 ll n,m;
6 struct edge
7 {
8 ll u,v,nxt;
9 }e[maxn<<1];
10 ll head[maxn],js;
11 void addage(ll u,ll v)
12 {
13 e[++js].u=u;e[js].v=v;
14 e[js].nxt=head[u];head[u]=js;
15 }
16 ll w[maxn];
17 ll dep[maxn],fat[maxn],siz[maxn],son[maxn];
18 void dfs(ll u,ll fa)
19 {
20 dep[u]=dep[fa]+1;
21 fat[u]=fa;
22 siz[u]=1;
23 for(ll i=head[u];i;i=e[i].nxt)
24 {
25 ll v=e[i].v;
26 if(v==fa)continue;
27 dfs(v,u);
28 siz[u]+=siz[v];
29 if(!son[u] || siz[son[u]]<siz[v])son[u]=v;
30 }
31 }
32 ll pos[maxn],top[maxn],fos[maxn],p;
33 void getpos(ll u,ll fa)
34 {
35 top[u]=fa;
36 pos[u]=++p;
37 fos[p]=u;
38 if(!son[u])return ;
39 getpos(son[u],fa);
40 for(ll i=head[u];i;i=e[i].nxt)
41 {
42 ll v=e[i].v;
43 if(v!=son[u] && v!=fat[u])getpos(v,v);
44 }
45 }
46 ll MAX,SUM;
47 ll _sum[maxn<<2],_max[maxn<<2];
48 void update(ll cur)
49 {
50 _sum[cur]=_sum[cur<<1]+_sum[cur<<1|1];
51 _max[cur]=max(_max[cur<<1],_max[cur<<1|1]);
52 }
53 void build(ll cur,ll l,ll r)
54 {
55 if(l==r)
56 {
57 _sum[cur]=_max[cur]=w[fos[l]];
58 return ;
59 }
60 ll mid=(l+r)>>1;
61 build(cur<<1,l,mid);
62 build(cur<<1|1,mid+1,r);
63 update(cur);
64 }
65 void query(ll cur,ll l,ll r,ll ql,ll qr)
66 {
67 if(ql<=l && r<=qr)
68 {
69 MAX=max(_max[cur],MAX);
70 SUM+=_sum[cur];
71 return ;
72 }
73 ll mid=(l+r)>>1;
74 if(ql<=mid)query(cur<<1,l,mid,ql,qr);
75 if(qr>mid)query(cur<<1|1,mid+1,r,ql,qr);
76 }
77 void ask(ll u,ll v)
78 {
79 ll tpu=top[u],tpv=top[v];
80 while(tpu!=tpv)
81 {
82 if(dep[tpu]<dep[tpv])
83 {
84 swap(u,v);swap(tpu,tpv);
85 }
86 query(1,1,n,pos[tpu],pos[u]);
87 u=fat[tpu];tpu=top[u];
88 }
89 if(dep[u]>dep[v])swap(u,v);
90 query(1,1,n,pos[u],pos[v]);
91 }
92 void change(ll cur,ll l,ll r,ll p,ll x)
93 {
94 if(l==r)
95 {
96 _max[cur]=_sum[cur]=x;
97 return ;
98 }
99 ll mid=(l+r)>>1;
100 if(p<=mid)change(cur<<1,l,mid,p,x);
101 else change(cur<<1|1,mid+1,r,p,x);
102 update(cur);
103 }
104 int main()
105 {
106 scanf("%lld",&n);
107 for(ll i=1,u,v;i<n;++i)
108 {
109 scanf("%lld%lld",&u,&v);
110 addage(u,v);addage(v,u);
111 }
112 for(int i=1;i<=n;++i)scanf("%lld",w+i);
113 scanf("%lld",&m);
114 dfs(1,0);
115 getpos(1,1);
116 build(1,1,n);
117 char s[10];
118 ll u,v;
119 while(m--)
120 {
121 scanf("%s%lld%lld",s,&u,&v);
122 if(s[1]=='H')change(1,1,n,pos[u],v);
123 else
124 {
125 MAX=-0x7fffffff,SUM=0;
126 ask(u,v);
127 printf("%lld\n",s[1]=='M'?MAX:SUM);
128 }
129 }
130 return 0;
131 }

LOJ10138的更多相关文章

随机推荐

  1. java混淆工具 字符串加密 程序加密 代码逻辑混淆 防止反编译

    混淆工具使用文档 ht-confusion-project1.0.0 目 录 1.功能介绍... 1 2.安装说明... 3 2.1Window查询jdk版本(点击开始菜单,输入cmd, 输入java ...

  2. spring boot 集成 Apache CXF 调用 .NET 服务端 WebService

    1. pom.xml加入 cxf 的依赖 <dependency> <groupId>org.apache.cxf</groupId> <artifactId ...

  3. linux系统搭建ftp服务器及创建用户使用

    linux 系统下搭建ftp服务器 ftp是什么 FTP是 File Transfer Protocol 文件传输协议的英文名称,用于在Internet上控制文件的双向传输. 同时它也是一个应用程序. ...

  4. ES6 对象拓展方法

    一,ES6 对象拓展方法 ES6为对象提供了一些拓展方法,下面列举几个比较常见的对象拓展方法.

  5. 图像处理 jpg png gif svg

    jpg 图像格式 高压缩的,除了文字,线条外,用jpg 处理 GIF 图像格式 高压缩的,动图  PNG 图像格式 PNG是一种可携式网络图像格式.PNG一开始便结合GIF及JPG两家之长,打算一举取 ...

  6. 【基础】1001_Hello,World!

    题目相关 [题目描述] 编写一个能够输出"Hello,World!"的程序,这个程序常常作为一个初学者接触一门新的编程语言所写的第一个程序,也经常用来测试开发.编译环境是否能够正常 ...

  7. Java 实现简单的 Socket 通信

    Java socket 封装了传输层的实现细节,开发人员可以基于 socket 实现应用层.本文介绍了 Java socket 简单用法. 1. 传输层协议 传输层包含了两种协议,分别是 TCP (T ...

  8. 获取json格式的数据变成了undefined!?

    今天在做一个简单的登陆功能时,当一切准备就绪,点击登陆时,什么都没发生..然后开始debug,打断点调试,然后发现了这个.向页面传递数据flag是true代表该用户的账号密码验证码等信息正确可以登录, ...

  9. Dubbo 配置的加载流程

    配置加载流程 在SpringBoot应用启动阶段,Dubbo的读取配置遵循以下原则 Dubbo支持了多层级的配置,按照预先定义的优先级自动实现配置之间的覆盖,最终所有的配置汇总到数据总线URL后,驱动 ...

  10. Writing in the science: Introducion

    1.what makes a good writing? 2.what makes a good writer? 1) have something to say 2) logical thinkin ...