这是树链剖分的入门题,也是我学树链剖分的第一题。

树链剖分:就是把树中和线段树联系起来,求(u,v)路径中权值的最大值和其路径的权值和。

入门blog:http://blog.sina.com.cn/s/blog_7a1746820100wp67.html

https://quartergeek.com/summary-of-heavy-light-decomposition/

kuangbin 菊苣的专题训练:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=28982#overview

我的第一树链

#include<bits/stdc++.h>
using namespace std;
#define  N 30010struct Edge
{int to,next;
}edge[N*2];int head[N],tot;
int top[N],fa[N],deep[N],num[N],p[N],fp[N],son[N],pos;void init()
{tot=0;memset(head,-1,sizeof(head));pos=0;memset(son,-1,sizeof(son));
}void addedge(int u,int v)
{edge[tot].to=v;edge[tot].next=head[u];head[u]=tot++;
}void dfs1(int u,int pre,int d)
{deep[u]=d;fa[u]=pre;num[u]=1;for (int i=head[u];i!=-1;i=edge[i].next){int v=edge[i].to;if (v!=pre){dfs1(v,u,d+1);num[u]+=num[v];if (son[u]==-1||num[v]>num[son[u]])son[u]=v;}}
}void getpos(int u,int sp)
{top[u]=sp;p[u]=pos++;fp[p[u]]=u;if (son[u]==-1) return;getpos(son[u],sp);for (int i=head[u];i!=-1;i=edge[i].next){int v=edge[i].to;if (v!=son[u]&&v!=fa[u]) getpos(v,v);}
}
struct node
{int l,r;int sum;int Max;
}tree[N*3];
void push_up(int i)
{tree[i].sum=tree[i<<1].sum+tree[i<<1|1].sum;tree[i].Max=max(tree[i<<1].Max,tree[i<<1|1].Max);
}
int s[N];void build(int i,int l,int r)
{tree[i].l=l;tree[i].r=r;if (l==r){tree[i].sum=tree[i].Max=s[fp[l]];return;}int mid=(l+r)>>1;build(i<<1,l,mid);build(i<<1|1,mid+1,r);push_up(i);
}
void update(int i,int k,int val)
{if (tree[i].l==k&&tree[i].r==k){tree[i].sum=tree[i].Max=val;return;}int mid=(tree[i].l+tree[i].r)/2;if (k<=mid) update(i<<1,k,val);else update(i<<1|1,k,val);push_up(i);
}int query_max(int i,int l,int r)
{if (tree[i].l==l&&tree[i].r==r)return tree[i].Max;int mid=(tree[i].l+tree[i].r)/2;if (r<=mid) return query_max(i<<1,l,r);else if (l>mid) return query_max(i<<1|1,l,r);else return max(query_max(i<<1,l,mid),query_max(i<<1|1,mid+1,r));
}int query_sum(int i,int l,int r)
{if (tree[i].l==l&&tree[i].r==r)return tree[i].sum;int mid=(tree[i].l+tree[i].r)/2;if (r<=mid) return query_sum(i<<1,l,r);else if (l>mid) return query_sum(i<<1|1,l,r);else return query_sum(i<<1,l,mid)+query_sum(i<<1|1,mid+1,r);
}int findmax(int u,int v)
{int f1=top[u],f2=top[v];int tmp=-12345667;while (f1!=f2){if (deep[f1]<deep[f2]){swap(f1,f2);swap(u,v);}tmp=max(tmp,query_max(1,p[f1],p[u]));u=fa[f1];f1=top[u];}if (deep[u]>deep[v]) swap(u,v);return max(tmp,query_max(1,p[u],p[v]));
}int findsum(int u,int v)
{int f1=top[u],f2=top[v];int tmp=0;while (f1!=f2){if (deep[f1]<deep[f2]){swap(f1,f2);swap(u,v);}tmp+=query_sum(1,p[f1],p[u]);u=fa[f1];f1=top[u];}if (deep[u]>deep[v]) swap(u,v);return tmp+query_sum(1,p[u],p[v]);
}int main()
{int n;int q;char op[20];int u,v;while(scanf("%d",&n) == 1){init();for(int i = 1;i < n;i++){scanf("%d%d",&u,&v);addedge(u,v);addedge(v,u);}for(int i = 1;i <= n;i++)scanf("%d",&s[i]);dfs1(1,0,0);getpos(1,1);build(1,0,pos-1);scanf("%d",&q);while(q--){scanf("%s%d%d",op,&u,&v);if(op[0] == 'C')update(1,p[u],v);//修改单点的值else if(strcmp(op,"QMAX") == 0)printf("%d\n",findmax(u,v));//查询u->v路径上点权的最大值else printf("%d\n",findsum(u,v));//查询路径上点权的和
        }}return 0;
}

份代码:

转载于:https://www.cnblogs.com/forgot93/p/4105573.html

树链剖分 - BZOJ 1036: [ZJOI2008]树的统计Count相关推荐

  1. 【BZOJ4515】游戏,树链剖分+永久化标记线段树维护线段信息(李超线段树)

    Time:2016.05.10 Author:xiaoyimi 转载注明出处谢谢 传送门 思路: 李超线段树 一开始听faebdc讲,并没有听的很懂ww 后来找到良心博文啊有木有 折越 首先可以把修改 ...

  2. BZOJ4012[HNOI2015]开店——树链剖分+可持久化线段树/动态点分治+vector

    题目描述 风见幽香有一个好朋友叫八云紫,她们经常一起看星星看月亮从诗词歌赋谈到 人生哲学.最近她们灵机一动,打算在幻想乡开一家小店来做生意赚点钱.这样的 想法当然非常好啦,但是她们也发现她们面临着一个 ...

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

    树链剖分: 把一棵树剖分为若干条链,然后利用数据结构(树状数组,SBT,Splay,线段树等等)去维护每一条链,复杂度 为O(logn),总体复杂度O(nlog²n) 步骤: ①将树的边分成重边和轻边 ...

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

    1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 3427  Solved: 1429 [Submi ...

  5. 【树链剖分】「ZJOI2008」树的统计

    前置知识 树链剖分的思想及能解决的问题 树链剖分用于将树分割成若干条链的形式,以维护树上路径的信息. 具体来说,将整棵树剖分为若干条链,使它组合成线性结构,然后用其他的数据结构维护信息. 树链剖分(树 ...

  6. BZOJ 1036 [ZJOI2008]树的统计Count

    以前动态树写过这个题,今天尝试树链剖分解决~ 模板题,就声明一点,线段树维护的是点权 View Code 1 #include <iostream> 2 #include <cstd ...

  7. 计蒜客 - Distance on the tree(树链剖分+离线处理+线段树)

    题目链接:点击查看 题目大意:给出一颗含有n个节点的树,每条边都有权值,现在给出m个询问,每次询问的格式为u,v,w,我们需要求出在路径u-v上,边权小于等于w的边的个数 题目分析:因为一开始不会主席 ...

  8. 【树链剖分】洛谷树(P3401)

    正题 P3401 题目大意 给你一棵树,让你进行以下操作 修改一条边的边权 查询一条路径的所有子路径异或值的和 解题思路 记下所有点到根节点的路径亦或值,那么查询就是所有点对的异或值之和 因为边权&l ...

  9. 【树链剖分】【线段树】树的统计(金牌导航 树链剖分-1)

    树的统计 金牌导航 树链剖分-1 题目大意 给出一棵树,让你做若干操作,操作如下: 1.修改一个节点的值 2.查询两个节点之间路径的最大值 3.查询两个节点之间路径的和 输入样例 4 1 2 2 3 ...

最新文章

  1. 数据库结构Sqlite与CoreData
  2. 原来deepin部署环境还是那么简单(只不过要用root权限)
  3. python写web难受-(2017)你最不建议使用的Python Web框架?
  4. HDU 1879(最小生成树问题,Prim)
  5. 【渝粤题库】国家开放大学2021春1026西方经济学(本)题目
  6. 前端现在到底需要什么样的人才
  7. 安装完VS2010之后再安装VS2012以后,发现VS工程编译出现--fatal error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏
  8. licode学习之编译篇--3
  9. 数睿数据、艾瑞咨询联合发布《2021年中国企业级无代码开发白皮书》
  10. Educational Codeforces Round 12 B. Shopping 暴力
  11. 剪切板记录管理工具:Paste Mac
  12. 交叉熵代价函数(作用及公式推导)
  13. Qt+MySQL实现数据库图书管理系统
  14. 服务器安全基础知识系列(三)关于网页木马
  15. 物联网视觉技术及应用
  16. Android中MVVM架构设计模式面试问题讲解
  17. @RestController当中的value 含义
  18. 1.2什么是HLSL
  19. 揭秘《英雄联盟》的游戏数据服务器
  20. python关键词共现图谱_如何用知网导出的关键词 几秒 生成共现矩阵及图谱 》完整版...

热门文章

  1. 《Linux内核设计与实现》读书笔记(十七)- 设备与模块
  2. C语言运算符优先级列表
  3. HDU Problem - 3338 Kakuro Extension (最大流,建图)
  4. 动态分配的const对象
  5. SQL数据库权限授予grant
  6. python爬虫之urllib库详解
  7. 复调制细化分析matlab,基于复调制的细化全矢谱分析研究
  8. Dalvik VM的主要特征
  9. 深入理解Java类加载器:Java类加载原理解析
  10. Eclipse 删除 空行