BZOJ 1036 [ZJOI2008]树的统计Count
以前动态树写过这个题,今天尝试树链剖分解决~
模板题,就声明一点,线段树维护的是点权
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cstdlib> 5 #include <algorithm> 6 7 #define N 50000 8 #define M 100000 9 #define INF 1e9 10 11 using namespace std; 12 13 int head[N],to[M],next[M]; 14 int sz[N],top[N],bh[N],fa[N],son[N],dep[N]; 15 int sum[N<<2],mx[N<<2],val[N],dat[N]; 16 int q[N]; 17 int n,cnt,tot,qu; 18 19 inline void add(int u,int v) 20 { 21 to[cnt]=v; next[cnt]=head[u]; head[u]=cnt++; 22 } 23 24 inline void prep() 25 { 26 int h=1,t=2,sta; 27 q[1]=1; dep[1]=1; 28 while(h<t) 29 { 30 sta=q[h++]; sz[sta]=1; 31 for(int i=head[sta];~i;i=next[i]) 32 if(to[i]!=fa[sta]) 33 { 34 fa[to[i]]=sta; 35 dep[to[i]]=dep[sta]+1; 36 q[t++]=to[i]; 37 } 38 } 39 for(int j=t-1;j>=1;j--) 40 { 41 sta=q[j]; 42 for(int i=head[sta];~i;i=next[i]) 43 if(to[i]!=fa[sta]) 44 { 45 sz[sta]+=sz[to[i]]; 46 if(sz[to[i]]>sz[son[sta]]) son[sta]=to[i]; 47 } 48 } 49 for(int i=1;i<t;i++) 50 { 51 sta=q[i]; 52 if(son[fa[sta]]==sta) top[sta]=top[fa[sta]];//不是重链顶部 53 else top[sta]=sta; 54 } 55 } 56 57 inline void rewrite() 58 { 59 for(int i=1;i<=n;i++) 60 if(top[i]==i) 61 for(int j=i;j;j=son[j])//每条重链的编号是连续的 62 { 63 bh[j]=++tot; 64 dat[tot]=val[j]; 65 } 66 } 67 68 inline void pushup(int x) 69 { 70 sum[x]=sum[x<<1]+sum[x<<1|1]; 71 mx[x]=max(mx[x<<1],mx[x<<1|1]); 72 } 73 74 inline void build(int u,int L,int R) 75 { 76 if(L==R) {sum[u]=mx[u]=dat[L];return;} 77 int MID=(L+R)>>1; 78 build(u<<1,L,MID); build(u<<1|1,MID+1,R); 79 pushup(u); 80 } 81 82 inline void read() 83 { 84 memset(head,-1,sizeof head); cnt=0; 85 scanf("%d",&n); 86 for(int i=1,a,b;i<n;i++) 87 { 88 scanf("%d%d",&a,&b); 89 add(a,b); add(b,a); 90 } 91 for(int i=1;i<=n;i++) scanf("%d",&val[i]); 92 prep(); 93 rewrite(); 94 build(1,1,tot); 95 } 96 97 inline int querysum(int u,int L,int R,int l,int r) 98 { 99 if(l<=L&&R<=r) return sum[u]; 100 int MID=(L+R)>>1,res=0; 101 if(l<=MID) res+=querysum(u<<1,L,MID,l,r); 102 if(MID<r) res+=querysum(u<<1|1,MID+1,R,l,r); 103 return res; 104 } 105 106 inline int getsum(int x,int y) 107 { 108 int res=0; 109 while(top[x]!=top[y]) 110 { 111 if(dep[top[x]]<dep[top[y]]) swap(x,y); 112 res+=querysum(1,1,tot,bh[top[x]],bh[x]); 113 x=fa[top[x]]; 114 } 115 if(bh[x]>bh[y]) swap(x,y); 116 res+=querysum(1,1,tot,bh[x],bh[y]); 117 return res; 118 } 119 120 inline int querymax(int u,int L,int R,int l,int r) 121 { 122 if(l<=L&&R<=r) return mx[u]; 123 int MID=(L+R)>>1,res=-INF; 124 if(l<=MID) res=max(res,querymax(u<<1,L,MID,l,r)); 125 if(MID<r) res=max(res,querymax(u<<1|1,MID+1,R,l,r)); 126 return res; 127 } 128 129 inline int getmax(int x,int y) 130 { 131 int res=-INF; 132 while(top[x]!=top[y]) 133 { 134 if(dep[top[x]]<dep[top[y]]) swap(x,y); 135 res=max(res,querymax(1,1,tot,bh[top[x]],bh[x])); 136 x=fa[top[x]]; 137 } 138 if(bh[x]>bh[y]) swap(x,y); 139 140 res=max(res,querymax(1,1,tot,bh[x],bh[y])); 141 return res; 142 } 143 144 inline void updata(int u,int L,int R,int pos,int sp) 145 { 146 if(L==R) {mx[u]=sum[u]=sp;return;} 147 int MID=(L+R)>>1; 148 if(pos<=MID) updata(u<<1,L,MID,pos,sp); 149 else updata(u<<1|1,MID+1,R,pos,sp); 150 pushup(u); 151 } 152 153 inline void go() 154 { 155 scanf("%d",&qu); 156 char str[10];int a,b; 157 while(qu--) 158 { 159 scanf("%s%d%d",str,&a,&b); 160 if(str[1]=='S') printf("%d\n",getsum(a,b)); 161 else if(str[1]=='M') printf("%d\n",getmax(a,b)); 162 else updata(1,1,tot,bh[a],b); 163 } 164 } 165 166 int main() 167 { 168 read(); 169 go(); 170 return 0; 171 }
转载于:https://www.cnblogs.com/proverbs/archive/2013/01/18/2867092.html
BZOJ 1036 [ZJOI2008]树的统计Count相关推荐
- BZOJ 1036: [ZJOI2008]树的统计Count
1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MB Submit: 3427 Solved: 1429 [Submi ...
- 树链剖分(bzoj 1036: [ZJOI2008]树的统计Count)
树链剖分: 把一棵树剖分为若干条链,然后利用数据结构(树状数组,SBT,Splay,线段树等等)去维护每一条链,复杂度 为O(logn),总体复杂度O(nlog²n) 步骤: ①将树的边分成重边和轻边 ...
- 树链剖分 - BZOJ 1036: [ZJOI2008]树的统计Count
这是树链剖分的入门题,也是我学树链剖分的第一题. 树链剖分:就是把树中和线段树联系起来,求(u,v)路径中权值的最大值和其路径的权值和. 入门blog:http://blog.sina.com.cn/ ...
- 洛谷 P2590 BZOJ 1036 [ZJOI2008]树的统计
Time limit 10000 ms//另外,BZOJ只算所有点的总时限,所以可能会放过一些原本会TLE的代码 Memory limit 165888 kB OS Linux SourceZJOI2 ...
- 【BZOJ 1036】 树的统计count
题目 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将以下面的形式来要求你对这棵树完成 一些操作: I. CHANGE u t : 把结点u的权值改为t II. QMAX u v: ...
- 1036: [ZJOI2008]树的统计Count
链剖 1 #include <cstdio> 2 #include <iostream> 3 #include <algorithm> 4 #include < ...
- 【BZOJ 1036】[ZJOI2008]树的统计Count
[题目链接]:http://www.lydsy.com/JudgeOnline/problem.php?id=1036 [题意] [题解] 树链剖分入门题; 每一条链维护一个线段树就好; uppest ...
- [bzoj1036][ZJOI2008]树的统计Count
Description 一棵树上有$n$个节点,编号分别为$1$到$n$,每个节点都有一个权值$w_i$. 有三种操作: $1.CHANGE\;u\;t$:把结点$u$的权值改为$t$; $2.QMA ...
- 【bzoj1036】 ZJOI2008—树的统计Count
http://www.lydsy.com/JudgeOnline/problem.php?id=1036 (题目链接) 题意 动态维护树上两点间最大权值和权值和. Solution 裸树链剖分. 这一 ...
最新文章
- C语言开发单片机如何避免全局变量过多混乱
- 一文梳理水下检测方法
- 《愤怒的小鸟》对移动互联网经营的启示
- c#获取本地ip地址网关子网掩码_教你如何修改路由器LAN口IP地址的方法
- 数据结构与算法 / 栈(stack)
- java入门5-asp.net关注
- python源码分析工具_python 域名分析工具实现代码
- android shape.xml 属性详解
- 使用PHP对word文档进行操作的方法
- Android【报错】xxx cannot be resolved to a type 错误解决方法
- LeetCode 496. 下一个更大元素 I(Next Greater Element I) 35
- 十行代码训练sklearn七种分类算法
- waitpid使用实例
- Adobe Photoshop Pro CC 2019及类似软件注册
- 如何彻底关闭UAC----之注册表篇
- 认知学派用计算机来比拟人,比拟:把人当物写或把物当人来写的一种修辞方法,前者称之为拟物,后者称之为拟人.如:①做人既不可翘尾巴,也不可夹着尾巴. ②蜡炬成灰泪始干....
- html简洁的错误页面设计,40个非常有创意的404错误页面设计
- 计算机组成原理简答题
- jrtplib学习目录及总结
- 排列组合问题,01234 五个数能组成多少个互不相同的三位数,且数字不重复。
热门文章
- html做旋转的五角星,如何用几何画板制作旋转的五角星
- java对象比较 hashcode_Java Objects.hash()与自己实现的hashCode()比较
- toad连接oracle12c,[20181107]低版本toad连接18c数据库问题.txt
- 020_Transfer穿梭框
- 055_Unicode字符官方标准六
- android layout include merge,Android 布局优化之include与merge
- c语言第四章循环程序设计,C语言程序设计教程第4章-循环结构程序设计
- python turtle应用实例_python-turtle-一个简单实例子
- 抽象类与接口的一个程序实现
- CAD2009软件安装资料及教程