HYSBZ 1036(树链剖分)
题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=28982#problem/E
题意:给定一棵树及树上的点权,要求三种操作:
1)CHANGE u t : 把结点u的权值改为t。
2)QMAX u v: 询问从点u到点v的路径上的节点的最大权值。
3)QSUM u v: 询问从点u到点v的路径上的节点的权值和
分析:树链剖分后就是线段树的单点修改,区间求和与区间求最值。。。
- #include <cstdio>
- #include <cstring>
- #include <string>
- #include <cmath>
- #include <iostream>
- #include <algorithm>
- #include <queue>
- #include <cstdlib>
- #include <stack>
- #include <vector>
- #include <set>
- #include <map>
- #define LL long long
- #define mod 10007
- #define inf 0x3f3f3f3f
- #define N 100010
- #define FILL(a,b) (memset(a,b,sizeof(a)))
- #define lson l,m,rt<<1
- #define rson m+1,r,rt<<1|1
- using namespace std;
- struct edge
- {
- int to,next;
- edge(){}
- edge(int to,int next):to(to),next(next){}
- }e[N<<];
- int head[N<<],tot;
- int top[N];//top[v]表示v所在的重链的顶端节点
- int fa[N];//父亲节点
- int dep[N];//深度
- int sz[N];//si[v]表示以v为根节点的子树的节点数
- int son[N];//重儿子
- int p[N];//p[v]表示v与其父亲节点的连边在线段树中的位置
- int fp[N];//与p数组相反
- int pos;//所有链构成的线段树总长度
- int sum[N<<],mx[N<<],a[N];
- void addedge(int u,int v)
- {
- e[tot]=edge(v,head[u]);
- head[u]=tot++;
- }
- void init()
- {
- tot=;FILL(head,-);
- pos=;FILL(son,-);
- }
- void dfs(int u,int f,int d)
- {
- dep[u]=d;sz[u]=;fa[u]=f;
- for(int i=head[u];~i;i=e[i].next)
- {
- int v=e[i].to;
- if(v==f)continue;
- dfs(v,u,d+);
- sz[u]+=sz[v];
- if(son[u]==-||sz[son[u]]<sz[v])son[u]=v;
- }
- }
- void getpos(int u,int sp)
- {
- top[u]=sp;
- p[u]=++pos;
- fp[pos]=u;
- if(son[u]==-)return;
- getpos(son[u],sp);
- for(int i=head[u];~i;i=e[i].next)
- {
- int v=e[i].to;
- if(v!=son[u]&&v!=fa[u])
- {
- getpos(v,v);
- }
- }
- }
- void Pushup(int rt)
- {
- int ls=rt<<,rs=ls|;
- sum[rt]=sum[ls]+sum[rs];
- mx[rt]=max(mx[ls],mx[rs]);
- }
- void build(int l,int r,int rt)
- {
- if(l==r)
- {
- mx[rt]=sum[rt]=a[fp[l]];
- return;
- }
- int m=(l+r)>>;
- build(lson);
- build(rson);
- Pushup(rt);
- }
- void update(int ps,int c,int l,int r,int rt)
- {
- if(l==r)
- {
- mx[rt]=sum[rt]=c;
- return;
- }
- int m=(l+r)>>;
- if(ps<=m)update(ps,c,lson);
- else update(ps,c,rson);
- Pushup(rt);
- }
- int querysum(int L,int R,int l,int r,int rt)
- {
- if(L<=l&&r<=R)
- return sum[rt];
- int m=(l+r)>>;
- int res=;
- if(L<=m)res+=querysum(L,R,lson);
- if(R>m)res+=querysum(L,R,rson);
- return res;
- }
- int querymax(int L,int R,int l,int r,int rt)
- {
- if(L<=l&&r<=R)
- return mx[rt];
- int m=(l+r)>>;
- int res=-inf;
- if(L<=m)res=max(res,querymax(L,R,lson));
- if(m<R)res=max(res,querymax(L,R,rson));
- return res;
- }
- int lca(int u,int v,int flag)
- {
- int fu=top[u],fv=top[v],res;
- if(flag)res=-inf;
- else res=;
- while(fu!=fv)
- {
- if(dep[fu]<dep[fv])
- {
- swap(fu,fv);
- swap(u,v);
- }
- if(flag)res=max(res,querymax(p[fu],p[u],,pos,));
- else res+=querysum(p[fu],p[u],,pos,);
- u=fa[fu];fu=top[u];
- }
- if(dep[u]>dep[v])swap(u,v);
- if(flag)res=max(res,querymax(p[u],p[v],,pos,));
- else res+=querysum(p[u],p[v],,pos,);
- return res;
- }
- int main()
- {
- int n,t,u,v,w;
- char op[];
- while(scanf("%d",&n)>)
- {
- init();
- for(int i=;i<n;i++)
- {
- scanf("%d%d",&u,&v);
- addedge(u,v);
- addedge(v,u);
- }
- for(int i=;i<=n;i++)scanf("%d",&a[i]);
- dfs(,,);
- getpos(,);
- build(,pos,);
- scanf("%d",&t);
- while(t--)
- {
- scanf("%s",op);
- scanf("%d%d",&u,&v);
- if(op[]=='S')
- {
- printf("%d\n",lca(u,v,));
- }
- else if(op[]=='M')
- {
- printf("%d\n",lca(u,v,));
- }
- else
- {
- update(p[u],v,,pos,);
- }
- }
- }
- }
HYSBZ 1036(树链剖分)的更多相关文章
- HYSBZ 1036树链剖分
一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把结点u的权值改为t II. QMAX u v: 询问从 ...
- HDU 3966 & POJ 3237 & HYSBZ 2243 树链剖分
树链剖分是一个很固定的套路 一般用来解决树上两点之间的路径更改与查询 思想是将一棵树分成不想交的几条链 并且由于dfs的顺序性 给每条链上的点或边标的号必定是连着的 那么每两个点之间的路径都可以拆成几 ...
- BZOJ 1036 && 树链剖分
还是太弱啊..各种数据结构只听过名字却没有一点概念..树链剖分也在这个范畴..今天来进一步深化一下教育改革推进全民素质提高. 性质 忘了在哪里看到的一篇blog有一句话讲得非常好,树链剖分不是一种数据 ...
- HYSBZ - 2243 树链剖分 + 线段树 处理树上颜色段数
用线段树处理颜色段数 记录区间内的颜色段数,区间右端点的颜色,区间右端点的颜色. int tr[maxn<<2], lc[maxn<<2], rc[maxn<<2] ...
- BZOJ 1036 [ZJOI2008]树的统计Count (树链剖分 - 点权剖分 - 单点权修改)
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1036 树链剖分模版题,打的时候注意点就行.做这题的时候,真的傻了,单词拼错检查了一个多小时 ...
- Luogu 2590 [ZJOI2008]树的统计 / HYSBZ 1036 [ZJOI2008]树的统计Count (树链剖分,LCA,线段树)
Luogu 2590 [ZJOI2008]树的统计 / HYSBZ 1036 [ZJOI2008]树的统计Count (树链剖分,LCA,线段树) Description 一棵树上有n个节点,编号分别 ...
- HYSBZ 1036 【树链剖分】
思路: 裸裸的树链剖分.... 树链剖分就是把一棵树分成若干重链和轻链...然后保证形成的线段树上每条链是连续存储的.然后这样就能用线段树进行维护了. 但是每次一定要保证是在同一条链里边....思路就 ...
- HYSBZ 1036 树的统计Count(树链剖分)题解
思路: 树链剖分,不知道说什么...我连模板都不会用 代码: #include<map> #include<ctime> #include<cmath> #incl ...
- BZOJ 1036: [ZJOI2008]树的统计Count [树链剖分]【学习笔记】
1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 14302 Solved: 5779[Submit ...
随机推荐
- Web前端,高性能优化
高性能HTML 一.避免使用iframe iframe也叫内联frame,可将一个HTML文档嵌入另一个HTML文档中. iframe的好处是,嵌入的文档独立于父文档,通常也借此使浏览器模拟多线程.缺 ...
- 从注册流程 分析如何安全退出多个Activity 多种方式(附DEMO)
前言 由于一个同学问到我如何按照一个流程走好之后回到首页,我以前看到过4个解决方案,后来发现有做个记录和总结的必要,就写了这篇博文.(之前看小强也写过一篇,这里通过自身的分析完整的总结一下以下6种 ...
- JSP的学习(3)——语法知识二之page指令
本篇接上一篇<JSP的学习(2)——语法知识一>,继续来学习JSP的语法.本文主要从JSP指令中的page指令,对其各个属性进行详细的学习: JSP指令: JSP指令是为JSP引擎而设计的 ...
- HDU 4893 Wow! Such Sequence!(2014年多校联合 第三场 G)(线段树)
磨了一天的线段树,不能说完全搞清楚,只能说有一个大概的了解,靠着模板才把这道题A了,只能说太弱~~! 题意: 初始时有一字符串,全为0. 三种操作: 1 k d - add 把d加到第k个数上去2 ...
- hdu 4710 Balls Rearrangement 数论
这个公倍数以后是循环的很容易找出来,然后循环以内的计算是打表找的规律,规律比较难表述,自己看代码吧.. #include <iostream> #include <cstdio> ...
- perl 使用cookie
use Net::SMTP; use LWP::UserAgent; use HTTP::Cookies; use HTTP::Headers; use HTTP::Response; use Enc ...
- linux c正则
c 正则 -------------------------------------------------- 标准的C和C++都不支持正则表达式,但有一些函数库可以辅助C/C++程序员完成这一 ...
- 【设计模式】Singleton模式C++实现
Singleton是设计模式中比较简单的一个.园中的朋友们应该都很熟悉了.前段时间参加xxx外企的面试,和面试官讨论C++的时候正好写了一个.当时由于在有些地方考虑不太周全,代码出现了一些疏漏.不过最 ...
- 14.4.3.4 Configuring InnoDB Buffer Pool Prefetching (Read-Ahead) 配置InnoDB Buffer pool 预读
14.4.3.4 Configuring InnoDB Buffer Pool Prefetching (Read-Ahead) 配置InnoDB Buffer pool 预读 一个预读请求 是一个I ...
- html浏览器兼容性的 JavaScript语法
1. 在FireFox中能够使用与HTML节点对象ID属性值同样的JS变量名称.可是IE中不行. 解决的方法:在命名上区分HTML节点对象ID属性值和JS变量 2. IE不支持JS ...