点此看题面

题解

这真的只是一道模板题:一个树链剖分套上一个线段树(令我窒息的组合)。

既然是模板题,那就直接上代码吧。

代码

#include<bits/stdc++.h>
#define N 30000
using namespace std;
int n,ee=0,tot=0,a[N+5],lnk[N+5],fa[N+5],Size[N+5],Depth[N+5],Wson[N+5],Top[N+5],Pos[N+5],Num[N+5];
int Sum[N<<2],Max[N<<2];
struct edge
{
int to,nxt;
}e[2*N+5];
inline char tc()
{
static char ff[100000],*A=ff,*B=ff;
return A==B&&(B=(A=ff)+fread(ff,1,100000,stdin),A==B)?EOF:*A++;
}
inline void read(int &x)
{
x=0;int f=1;char ch;
while(!isdigit(ch=tc())) if(ch=='-') f=-1;
while(x=(x<<3)+(x<<1)+ch-'0',isdigit(ch=tc()));
x*=f;
}
inline void write(int x)
{
if(x<0) putchar('-'),x=-x;
if(x>9) write(x/10);
putchar(x%10+'0');
}
inline void read_string(string &st)
{
st="";char ch;
while((ch=tc())<'A'||ch>'Z');
while(st+=ch,(ch=tc())>='A'&&ch<='Z');
}
inline void add(int x,int y)
{
e[++ee]=(edge){y,lnk[x]},lnk[x]=ee;
}
inline void dfs1(int x)//第一遍DFS,预处理出每个节点的父亲、深度、重儿子以及子树大小
{
register int i;Size[x]=1;
for(i=lnk[x];i;i=e[i].nxt)
if(e[i].to^fa[x]) fa[e[i].to]=x,Depth[e[i].to]=Depth[x]+1,dfs1(e[i].to),Size[x]+=Size[e[i].to],(Size[e[i].to]>Size[Wson[x]]?Wson[x]=e[i].to:0);
}
inline void dfs2(int x,int tp)//第二遍DFS,根据先前预处理出的重儿子,剖分出轻重链
{
register int i;Top[Num[Pos[x]=++tot]=x]=tp;
if(Wson[x]) dfs2(Wson[x],tp);
for(i=lnk[x];i;i=e[i].nxt)
if(e[i].to!=fa[x]&&e[i].to!=Wson[x]) dfs2(e[i].to,e[i].to);
}
inline void PushUp(int rt)
{
Sum[rt]=Sum[rt<<1]+Sum[rt<<1|1],Max[rt]=max(Max[rt<<1],Max[rt<<1|1]);
}
inline void Build(int l,int r,int rt)//一个朴素的建树过程
{
if(l==r)
{
Sum[rt]=Max[rt]=a[Num[l]];
return;
}
int mid=l+r>>1;
Build(l,mid,rt<<1),Build(mid+1,r,rt<<1|1),PushUp(rt);
}
inline void Update(int l,int r,int rt,int x,int v)//单点修改
{
if(l==r)
{
Sum[rt]=Max[rt]=v;
return;
}
int mid=l+r>>1;
(mid>=x?Update(l,mid,rt<<1,x,v):Update(mid+1,r,rt<<1|1,x,v)),PushUp(rt);
}
inline int Query_Max(int l,int r,int rt,int L,int R)//查询区间最大值
{
if(L>R) L^=R,R^=L,L^=R;
if(L<=l&&r<=R) return Max[rt];
int mid=l+r>>1,res=-1e9;
if(L<=mid) res=max(res,Query_Max(l,mid,rt<<1,L,R));
if(R>mid) res=max(res,Query_Max(mid+1,r,rt<<1|1,L,R));
return res;
}
inline int Query_Sum(int l,int r,int rt,int L,int R)//查询区间和
{
if(L>R) L^=R,R^=L,L^=R;
if(L<=l&&r<=R) return Sum[rt];
int mid=l+r>>1,res=0;
if(L<=mid) res+=Query_Sum(l,mid,rt<<1,L,R);
if(R>mid) res+=Query_Sum(mid+1,r,rt<<1|1,L,R);
return res;
}
inline int Qmax(int s1,int s2)//对数据进行处理,并调用线段树的Query_Max()函数来求出答案
{
int res=-1e9;
while(Top[s1]^Top[s2])
{
if(Depth[Top[s1]]<Depth[Top[s2]]) s1^=s2,s2^=s1,s1^=s2;
res=max(res,Query_Max(1,n,1,Pos[Top[s1]],Pos[s1])),s1=fa[Top[s1]];
}
if(Depth[s1]<Depth[s2]) s1^=s2,s2^=s1,s1^=s2;
return max(res,Query_Max(1,n,1,Pos[s1],Pos[s2]));
}
inline int Qsum(int s1,int s2)//对数据进行处理,并调用线段树的Query_Sum()函数来求出答案
{
int res=0;
while(Top[s1]^Top[s2])
{
if(Depth[Top[s1]]<Depth[Top[s2]]) s1^=s2,s2^=s1,s1^=s2;
res+=Query_Sum(1,n,1,Pos[Top[s1]],Pos[s1]),s1=fa[Top[s1]];
}
if(Depth[s1]<Depth[s2]) s1^=s2,s2^=s1,s1^=s2;
return res+Query_Sum(1,n,1,Pos[s1],Pos[s2]);
}
int main()
{
freopen("a.in","r",stdin);
register int i;int x,y;
for(read(n),i=1;i<n;++i)
read(x),read(y),add(x,y),add(y,x);
for(i=1;i<=n;++i)
read(a[i]);
dfs1(1),dfs2(1,1),Build(1,n,1);
int Q;read(Q);
while(Q--)
{
string st;
read_string(st),read(x),read(y);
if(st=="CHANGE") Update(1,n,1,Pos[x],y);
else if(st=="QMAX") write(Qmax(x,y)),putchar('\n');
else if(st=="QSUM") write(Qsum(x,y)),putchar('\n');
}
return 0;
}

【BZOJ1036】[ZJOI2008] 树的统计Count(一道可怕的模板题:树剖+线段树)的更多相关文章

  1. [置顶] bzoj 1036 树的统计Count 点权值模板

    树链剖分 点权型可做模板,链路剖分的思想把点hash到线段树的上,然后可通过n*(log(n)*log(n))的复杂度在树上操作,在线段树上能操作的在链路上都能操作. #include<cstd ...

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

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

  3. [BZOJ1036][ZJOI2008]树的统计Count 解题报告|树链剖分

    树链剖分 简单来说就是数据结构在树上的应用.常用的为线段树splay等.(可现在splay还不会敲囧) 重链剖分: 将树上的边分成轻链和重链. 重边为每个节点到它子树最大的儿子的边,其余为轻边. 设( ...

  4. bzoj1036 [ZJOI2008]树的统计Count

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

  5. bzoj1036 [ZJOI2008]树的统计Count 树链剖分模板题

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

  6. bzoj千题计划124:bzoj1036: [ZJOI2008]树的统计Count

    http://www.lydsy.com/JudgeOnline/problem.php?id=1036 树链剖分板子题 #include<cstdio> #include<iost ...

  7. 【lct】bzoj1036 [ZJOI2008]树的统计Count

    题意:给你一棵树,点带权,支持三种操作:单点修改:询问链上和:询问链上max. 这里的Query操作用了与上一题不太一样的做法(上一题用那种做法,因为在边带权的情况下换根太困难啦): 先ChangeR ...

  8. 题解 [ZJOI2008]树的统计Count

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

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

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

随机推荐

  1. 《OD面试》Java软件工程师

    一.JVM自动内存管理机制 1. Java内存模型 1.1 由所有线程共享的数据区: 1.1.1 方法区(Method Area), Non-Heap(非堆) 用户存储已被虚拟机加载的类信息.常量.静 ...

  2. hdu1695(莫比乌斯反演模板)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1695 题意: 对于 a, b, c, d, k . 有 x 属于 [a, b],  y 属于 [c, ...

  3. 洛谷P3649 [APIO2014]回文串(回文自动机)

    传送门 话说回文自动机我自己都还没搞懂呢…… 等到时候会了再来填坑 //minamoto #include<cstdio> #include<cstring> #define ...

  4. 解读人:刘佳维,Spectral Clustering Improves Label-Free Quantification of Low-Abundant Proteins(谱图聚类改善了低丰度蛋白的无标记定量)

    发表时间:(2019年4月) IF:3.95 单位: 维也纳医科大学: 欧洲生物信息研究所(EMBL-EBI): 分子病理学研究所: 奥地利科学院分子生物技术研究所: Gregor Mendel分子植 ...

  5. BootStrap系统

    BootStrsp的引入: <!-- 新 Bootstrap 核心 CSS 文件 --> <link rel="stylesheet" href="// ...

  6. d190305面试题01总结

    题目一: 题目二: 题目三: 类中的某个成员变量可以被他和他的子类访问,应该用protected 知识点: 1.类中public修饰的属性,方法可以被该类,子孙类和外部类访问. 2.类中protect ...

  7. 当重装eclipse后,给现有web项目添加tomcat的构建路径

    在eclipse“首选项”-“service environment”中配置好tomcat后,给现有web项目添加构建路径: 1.选中一个web项目右键选中“构建路径”-“配置构建路径”

  8. 忘记mysql数据库密码时进行修改方法

    长时间没有使用数据库了,或者把密码改完之后就忘了数据库密码,不能正常进入数据库,也无法修改密码,有一个简单的常用修改密码方式: 1.首先找到和打开mysql.exe和mysqld.exe所在的文件夹( ...

  9. Unity UGUI暂停按钮切换图片代码

    using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; ...

  10. Java面向对象_对象一一对应关系和this关键字

    一.打个比方,一个人有一个身份证号,一个身份证号对应一个人.一个英雄对应一把武器,一把武器对应一个英雄.生活中很多对象都存在一一对应关系,那么一一对应关系在代码中是如何实现的呢?举个例子,英雄和武器一 ...