树剖裸题

#include <iostream>
#include <cstdio>
using namespace std;
int n, uu, vv, hea[30005], ecnt, w[30005], ww[30005], dep[30005], cnt;
int idx[30005], son[30005], fa[30005], top[30005], q, wt[30005], siz[30005];
char ss[15];
struct Edge{
int too, nxt;
}edge[60005];
void add_edge(int fro, int too){
edge[++ecnt].nxt = hea[fro];
edge[ecnt].too = too;
hea[fro] = ecnt;
}
struct SGT{
int sum[120005];
int zdz[120005];
void build(int o, int l, int r){
if(l==r) zdz[o] = sum[o] = wt[l];
else{
int mid=(l+r)>>1;
int lson=o<<1;
int rson=lson|1;
zdz[lson] = zdz[rson] = -0x3f3f3f3f;
if(l<=mid) build(lson, l, mid);
if(mid<r) build(rson, mid+1, r);
sum[o] = sum[lson] + sum[rson];
zdz[o] = max(zdz[lson], zdz[rson]);
}
}
void change(int o, int l, int r, int x, int k){
if(l>=x && r<=x) sum[o] = zdz[o] = k;
else{
int mid=(l+r)>>1;
int lson=o<<1;
int rson=lson|1;
if(x<=mid) change(lson, l, mid, x, k);
if(mid<x) change(rson, mid+1, r, x, k);
sum[o] = sum[lson] + sum[rson];
zdz[o] = max(zdz[lson], zdz[rson]);
}
}
int querySum(int o, int l, int r, int x, int y){
if(l>=x && r<=y) return sum[o];
else{
int mid=(l+r)>>1;
int lson=o<<1;
int rson=lson|1;
int ans=0;
if(x<=mid) ans += querySum(lson, l, mid, x, y);
if(mid<y) ans += querySum(rson, mid+1, r, x, y);
return ans;
}
}
int queryZdz(int o, int l, int r, int x, int y){
if(l>=x && r<=y) return zdz[o];
else{
int mid=(l+r)>>1;
int lson=o<<1;
int rson=lson|1;
int ans=-0x3f3f3f3f;
if(x<=mid) ans = max(ans, queryZdz(lson, l, mid, x, y));
if(mid<y) ans = max(ans, queryZdz(rson, mid+1, r, x, y));
return ans;
}
}
}sgt;
void dfs1(int x, int f){
fa[x] = f;
dep[x] = dep[f] + 1;
siz[x] = 1;
int maxSon=-1;
for(int i=hea[x]; i; i=edge[i].nxt){
int t=edge[i].too;
if(t==f) continue;
dfs1(t, x);
siz[x] += siz[t];
if(maxSon<siz[t]){
maxSon = siz[t];
son[x] = t;
}
}
}
void dfs2(int x, int topf){
top[x] = topf;
idx[x] = ++cnt;
wt[cnt] = w[x];
if(!son[x]) return ;
dfs2(son[x], topf);
for(int i=hea[x]; i; i=edge[i].nxt){
int t=edge[i].too;
if(t==fa[x] || t==son[x]) continue;
dfs2(t, t);
}
}
int queryRangeSum(int uu, int vv){
int ans=0;
while(top[uu]!=top[vv]){
if(dep[top[uu]]<dep[top[vv]]) swap(uu, vv);
ans += sgt.querySum(1, 1, n, idx[top[uu]], idx[uu]);
uu = fa[top[uu]];
}
if(dep[uu]>dep[vv]) swap(uu, vv);
ans += sgt.querySum(1, 1, n, idx[uu], idx[vv]);
return ans;
}
int queryRangeZdz(int uu, int vv){
int ans=-0x3f3f3f3f;
while(top[uu]!=top[vv]){
if(dep[top[uu]]<dep[top[vv]]) swap(uu, vv);
ans = max(ans, sgt.queryZdz(1, 1, n, idx[top[uu]], idx[uu]));
uu = fa[top[uu]];
}
if(dep[uu]>dep[vv]) swap(uu, vv);
ans = max(ans, sgt.queryZdz(1, 1, n, idx[uu], idx[vv]));
return ans;
}
int main(){
cin>>n;
for(int i=1; i<n; i++){
scanf("%d %d", &uu, &vv);
add_edge(uu, vv);
add_edge(vv, uu);
}
for(int i=1; i<=n; i++)
scanf("%d", &w[i]);
dep[1] = 1;
dfs1(1, 0);
dfs2(1, 1);
sgt.build(1, 1, n);
cin>>q;
while(q--){
scanf("%s %d %d", ss, &uu, &vv);
if(ss[1]=='H') sgt.change(1, 1, n, idx[uu], vv);
if(ss[1]=='M') printf("%d\n", queryRangeZdz(uu, vv));
if(ss[1]=='S') printf("%d\n", queryRangeSum(uu, vv));
}
return 0;
}

luogu2590 [ZJOI2008]树的统计的更多相关文章

  1. BZOJ1036:[ZJOI2008]树的统计——题解

    http://www.lydsy.com/JudgeOnline/problem.php?id=1036 题目描述 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w. 我们将以下面的形式来 ...

  2. BZOJ 1036: [ZJOI2008]树的统计Count [树链剖分]【学习笔记】

    1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 14302  Solved: 5779[Submit ...

  3. bzoj1036 [ZJOI2008]树的统计Count

    1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 12646  Solved: 5085 [Subm ...

  4. BZOJ 1036: [ZJOI2008]树的统计Count

    1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 14354  Solved: 5802 [Subm ...

  5. 【BZOJ1036】[ZJOI2008]树的统计Count 树链剖分

    [BZOJ1036][ZJOI2008]树的统计Count Description 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将以下面的形式来要求你对这棵树完成一些操作: I. ...

  6. bzoj 1036 [ZJOI2008]树的统计Count(树链剖分,线段树)

    1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 10677  Solved: 4313[Submit ...

  7. Bzoj 1036: [ZJOI2008]树的统计Count 树链剖分,LCT

    1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 11102  Solved: 4490[Submit ...

  8. 数据结构(LCT动态树):BZOJ 1036: [ZJOI2008]树的统计Count

    1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 12266  Solved: 4945[Submit ...

  9. BZOJ 1036: [ZJOI2008]树的统计Count( 树链剖分 )

    树链剖分... 不知道为什么跑这么慢 = = 调了一节课啊跪.. ------------------------------------------------------------------- ...

随机推荐

  1. c# 字符串的首字母大写转换 方法

    方法1: s.Substring(0,1).ToUpper()+s.Substring(1);  方法2: s = System.Threading.Thread.CurrentThread.Curr ...

  2. Java 面向对象,封装,继承

    1相关概念的理解 1.1面向过程.面向对象 面向过程与面向对象都是编程中,编写程序的一种思维方式. 面向过程的程序设计方式,是遇到一件事时,思考“我该怎么做”,然后一步步实现的过程.(职员思想) 面向 ...

  3. Swing编程概述

    Swing作为AWT组件的“强化版”,它的产生主要是为了克服AWT构建的GUI,无法在所有平台都通用的问题.允许编程人员跨平台时指定统一的GUI显示风格也是Swing的最大优势.Swing是AWT的补 ...

  4. Java实现的断点续传功能

    代码中已经加入了注释,需要的朋友可以直接参考代码中的注释.下面直接上功能实现的主要代码: import java.io.File; import java.io.FileNotFoundExcepti ...

  5. SpringBoot 封装返回类以及session 添加获取

    1.创建返回类Result public class Result<T>{ /*错误码*/ private Integer code; /*提示信息 */ private String m ...

  6. 浅析HTML的元素类型及其转换

    大家都知道html是由标签元素组成的,在了解元素的类型转换之前,让我们先来了解一下html的元素类型. 一.html元素类型分为两种:块级元素和内联元素,内联元素又被称为行内元素.  常见的块级元素有 ...

  7. C# 对接腾讯企业邮接口----get/post请求

    在无所知之的情况下.来了一个对接接口的任务,没办法,只能根据前端时候的经验硬着头皮上了,随后又整理了一下写的方法,主要包括了部门的创建.更新.删除.查找.然后他们的前提是token的获取 首先HTTP ...

  8. cmd_ping命令

    ping命令是网络命令里的核心命令,同时也是黑客入侵的基础命令.下面和大家分享一下ping命令的基础知识和一般用法. 以ping百度公司域名为例,介绍ping命令相关内容. 一.ping命令基础知识 ...

  9. CentOS7.3+MySQL5.7+Apache2.4+PHP7.1+phpMyAdmin4.7+JDK1.8+SVN1.6+Jenkins2.1环境搭建

    CentOS7.3+MySQL5.7+Apache2.4+PHP7.1+phpMyAdmin4.7+JDK1.8+SVN1.6+Jenkins2.1环境搭建 1.安装CentOS7.3虚拟机安装说明: ...

  10. WPF中,DataGrid最左边多出一行的解决方案

        这种情况下,请在DataGrid的属性里加上这个属性:   RowHeaderWidth="0" 必须赋值为0,不能不赋值,也不能赋其他值. 问题解决.