以前动态树写过这个题,今天尝试树链剖分解决~

模板题,就声明一点,线段树维护的是点权

View Code

  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相关推荐

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

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

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

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

  3. 树链剖分 - BZOJ 1036: [ZJOI2008]树的统计Count

    这是树链剖分的入门题,也是我学树链剖分的第一题. 树链剖分:就是把树中和线段树联系起来,求(u,v)路径中权值的最大值和其路径的权值和. 入门blog:http://blog.sina.com.cn/ ...

  4. 洛谷 P2590 BZOJ 1036 [ZJOI2008]树的统计

    Time limit 10000 ms//另外,BZOJ只算所有点的总时限,所以可能会放过一些原本会TLE的代码 Memory limit 165888 kB OS Linux SourceZJOI2 ...

  5. 【BZOJ 1036】 树的统计count

    题目 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将以下面的形式来要求你对这棵树完成 一些操作: I. CHANGE u t : 把结点u的权值改为t II. QMAX u v: ...

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

    链剖 1 #include <cstdio> 2 #include <iostream> 3 #include <algorithm> 4 #include < ...

  7. 【BZOJ 1036】[ZJOI2008]树的统计Count

    [题目链接]:http://www.lydsy.com/JudgeOnline/problem.php?id=1036 [题意] [题解] 树链剖分入门题; 每一条链维护一个线段树就好; uppest ...

  8. [bzoj1036][ZJOI2008]树的统计Count

    Description 一棵树上有$n$个节点,编号分别为$1$到$n$,每个节点都有一个权值$w_i$. 有三种操作: $1.CHANGE\;u\;t$:把结点$u$的权值改为$t$; $2.QMA ...

  9. 【bzoj1036】 ZJOI2008—树的统计Count

    http://www.lydsy.com/JudgeOnline/problem.php?id=1036 (题目链接) 题意 动态维护树上两点间最大权值和权值和. Solution 裸树链剖分. 这一 ...

最新文章

  1. C语言开发单片机如何避免全局变量过多混乱
  2. 一文梳理水下检测方法
  3. 《愤怒的小鸟》对移动互联网经营的启示
  4. c#获取本地ip地址网关子网掩码_教你如何修改路由器LAN口IP地址的方法
  5. 数据结构与算法 / 栈(stack)
  6. java入门5-asp.net关注
  7. python源码分析工具_python 域名分析工具实现代码
  8. android shape.xml 属性详解
  9. 使用PHP对word文档进行操作的方法
  10. Android【报错】xxx cannot be resolved to a type 错误解决方法
  11. LeetCode 496. 下一个更大元素 I(Next Greater Element I) 35
  12. 十行代码训练sklearn七种分类算法
  13. waitpid使用实例
  14. Adobe Photoshop Pro CC 2019及类似软件注册
  15. 如何彻底关闭UAC----之注册表篇
  16. 认知学派用计算机来比拟人,比拟:把人当物写或把物当人来写的一种修辞方法,前者称之为拟物,后者称之为拟人.如:①做人既不可翘尾巴,也不可夹着尾巴. ②蜡炬成灰泪始干....
  17. html简洁的错误页面设计,40个非常有创意的404错误页面设计
  18. 计算机组成原理简答题
  19. jrtplib学习目录及总结
  20. 排列组合问题,01234 五个数能组成多少个互不相同的三位数,且数字不重复。

热门文章

  1. html做旋转的五角星,如何用几何画板制作旋转的五角星
  2. java对象比较 hashcode_Java Objects.hash()与自己实现的hashCode()比较
  3. toad连接oracle12c,[20181107]低版本toad连接18c数据库问题.txt
  4. 020_Transfer穿梭框
  5. 055_Unicode字符官方标准六
  6. android layout include merge,Android 布局优化之include与merge
  7. c语言第四章循环程序设计,C语言程序设计教程第4章-循环结构程序设计
  8. python turtle应用实例_python-turtle-一个简单实例子
  9. 抽象类与接口的一个程序实现
  10. CAD2009软件安装资料及教程