2460 树的统计

        2008年省队选拔赛浙江

时间限制: 2 s    空间限制: 128000 KB    题目等级 : 大师 Master

题目描述 Description

一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w。

我们将以下面的形式来要求你对这棵树完成一些操作:

  1. I.                    CHANGE u t : 把结点u的权值改为t
  2. II.                 QMAX u v: 询问从点u到点v的路径上的节点的最大权值
  3. III.               QSUM u v: 询问从点u到点v的路径上的节点的权值和

 

注意:从点u到点v的路径上的节点包括u和v本身

输入描述 Input Description

输入文件的第一行为一个整数n,表示节点的个数。

接下来n – 1行,每行2个整数a和b,表示节点a和节点b之间有一条边相连。

       接下来n行,每行一个整数,第i行的整数wi表示节点i的权值。

接下来1行,为一个整数q,表示操作的总数。

接下来q行,每行一个操作,以“CHANGE u t”或者“QMAX u v”或者“QSUM u v”的形式给出。

输出描述 Output Description

对于每个“QMAX”或者“QSUM”的操作,每行输出一个整数表示要求输出的结果。

样例输入 Sample Input

4

1 2

2 3

4 1

4 2 1 3

12

QMAX 3 4

QMAX 3 3

QMAX 3 2

QMAX 2 3

QSUM 3 4

QSUM 2 1

CHANGE 1 5

QMAX 3 4

CHANGE 3 6

QMAX 3 4

QMAX 2 4

QSUM 3 4

样例输出 Sample Output

4

1

2

2

10

6

5

6

5

16

数据范围及提示 Data Size & Hint

对于100%的数据,保证1<=n<=30000,0<=q<=200000;中途操作中保证每个节点的权值w在-30000到30000之间。

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #define maxn 300001
  5 using namespace std;
  6 int head[maxn],dep[maxn],fa[maxn],a[maxn];
  7 int pos[maxn],top[maxn],size[maxn],son[maxn];
  8 int tot,n,m,cnt,maxsize,x,y,num;
  9 struct Edge{int next,to;}e[maxn<<1];
 10 struct Node{int l,r,max,sum;}tre[maxn<<2];
 11 int read(){
 12     int x=0,f=1;char c=getchar();
 13     while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
 14     while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
 15     return x*f;
 16 }
 17 int max(int a,int b){if(a>b)return a;else return b;}
 18 void Add_Edge(int u,int v){
 19     e[++num].to=v;e[num].next=head[u];head[u]=num;
 20 }
 21 void DFS_First(int now,int pre,int deepth){
 22     dep[now] = deepth; fa[now] = pre; size[now] = 1;
 23     for(int i=head[now];i;i=e[i].next){
 24         int v=e[i].to;
 25         if(v!=pre){
 26             DFS_First(v,now,deepth+1);
 27             size[now] += size[v];
 28             if(son[now]==-1||size[v]>size[son[now]])
 29                 son[now]=v;
 30         }
 31     }
 32 }
 33 void Get_Pos(int u,int Top){
 34     int k=0;maxsize++;
 35     pos[u]=maxsize;top[u]=Top;
 36     if(!son[u])return;
 37     Get_Pos(son[u],Top);
 38     for(int i=head[u];i;i=e[i].next)
 39         if(dep[e[i].to]>dep[u]&&e[i].to!=son[u])
 40             Get_Pos(e[i].to,e[i].to);
 41     return;
 42 }
 43 void Build(int now,int l,int r){
 44     tre[now].l=l;tre[now].r=r;
 45     if(l==r){
 46         tre[now].sum=tre[now].max=0;return ;
 47     }
 48     int mid=(l+r)>>1;
 49     Build(now<<1,l,mid);Build(now<<1|1,mid+1,r);
 50     tre[now].sum=tre[now<<1].sum+tre[now<<1|1].sum;
 51     tre[now].max=max(tre[now<<1].max,tre[now<<1|1].max);
 52
 53 }
 54 void Insert(int now,int poss,int val){
 55     if(tre[now].l==tre[now].r){
 56         tre[now].sum=tre[now].max=val;return;
 57     }
 58     int mid=(tre[now].l+tre[now].r)/2;
 59     if(poss<=mid)Insert(now<<1,poss,val);
 60     else if(poss>mid)Insert(now<<1|1,poss,val);
 61     tre[now].sum=tre[now<<1].sum+tre[now<<1|1].sum;
 62     tre[now].max=max(tre[now<<1].max,tre[now<<1|1].max);
 63 }
 64 int QueryMax(int now,int l,int r){
 65     if(l<=tre[now].l&&tre[now].r<=r)return tre[now].max;
 66     int mid=(tre[now].l+tre[now].r)>>1,total=-1e9;
 67     if(l<=mid)total=max(total,QueryMax(now<<1,l,r));
 68     if(r>mid)total=max(total,QueryMax(now<<1|1,l,r));
 69     return total;
 70 }
 71 int QuerySum(int now,int l,int r){
 72     if(l<=tre[now].l&&tre[now].r<=r)return tre[now].sum;
 73     int mid=(tre[now].l+tre[now].r)>>1,total=0;
 74     if(l<=mid)total+=QuerySum(now<<1,l,r);
 75     if(r>mid)total+=QuerySum(now<<1|1,l,r);
 76     return total;
 77 }
 78 int SolveMax(int u,int v){
 79     int ans=-1e9;
 80     while(top[u]!=top[v]){
 81         if(dep[top[u]]<dep[top[v]])swap(u,v);
 82         ans=max(ans,QueryMax(1,pos[top[u]],pos[u]));
 83         u=fa[top[u]];
 84     }
 85     if(pos[u]>pos[v]) swap(u,v);
 86     ans=max(ans,QueryMax(1,pos[u],pos[v]));
 87     return ans;
 88 }
 89 int SolveSum(int u,int v){
 90     int ans=0;
 91     while(top[u]!=top[v]){
 92         if(dep[top[u]]<dep[top[v]])swap(u,v);
 93         ans+=QuerySum(1,pos[top[u]],pos[u]);
 94         u=fa[top[u]];
 95     }
 96     if(pos[u]>pos[v])swap(u,v);
 97     ans+=QuerySum(1,pos[u],pos[v]);
 98     return ans;
 99 }
100 int main(){
101     n=read();
102     for(int i=1;i<n;i++){
103         x=read();y=read();
104         Add_Edge(x,y);Add_Edge(y,x);
105     }
106     for(int i=1;i<=n;i++) a[i]=read();
107     DFS_First(1,0,0);
108     Get_Pos(1,1);
109     Build(1,1,maxsize);
110     for(int i=1;i<=n;i++)
111     Insert(1,pos[i],a[i]);
112     m=read();char sp[25];
113     while(m--){
114         scanf("%s",sp);scanf("%d%d",&x,&y);
115         if(sp[0]=='C')a[x]=y,Insert(1,pos[x],y);
116         else{
117             if(sp[1]=='M') printf("%d\n",SolveMax(x,y));
118             else printf("%d\n",SolveSum(x,y));
119         }
120     }
121     return 0;
122 }

转载于:https://www.cnblogs.com/suishiguang/p/6502339.html

Codevs 2460 == BZOJ 1036 树的统计相关推荐

  1. bzoj 1036 树的统计Count

    题意:... 解法:树链剖分,对点进行重编号,这样的话线段树中点的信息就是树中点的信息...别的很常规... 1 #include<cstdio> 2 #include<cstrin ...

  2. 树链剖分入门+HYSBZ - 1036树的统计Count

    今天学习了树链剖分,记录一下. [题目背景] HYSBZ - 1036树的统计Count [题目分析] 题目要求求任意结点之间路径的和以及路径上最大的结点,还有可能修改.如果正常做可能会很复杂(我也不 ...

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

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

  4. 【BZOJ】【1036】树的统计

    嗯这题是一道对树进行动态修改&查询的经典题目,可以拿来练习树链剖分~ 啊对于这种动态修改&查询的题目,我们最喜闻乐见的就是在一个序列上去做了,毕竟可以直接套各种数据结构模版啊,比如线段 ...

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

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

  6. [ZJOI2008][BZOJ1036] 树的统计count

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

  7. codevs 1729 单词查找树

    二次联通门 : codevs 1729 单词查找树 /*codevs 1729 单词查找树Trie树统计节点个数建一棵Trie树插入单词时每新开一个节点就计数器加1*/ #include <cs ...

  8. 洛谷——P2590 [ZJOI2008]树的统计(树链剖分模板练手)

    P2590 [ZJOI2008]树的统计 I. CHANGE u t : 把结点u的权值改为t II. QMAX u v: 询问从点u到点v的路径上的节点的最大权值 III. QSUM u v: 询问 ...

  9. 洛谷 P2590 [ZJOI2008]树的统计

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

最新文章

  1. 长安大学微型计算机原理与接口技术答案,长安大学微机原理与接口技术A卷答案...
  2. python合并excel文件关键字_使用 Python 合并多个格式一致的 Excel 文件,Excel 表格...
  3. Ubuntu18.04安装cuDNN和Tensorflow的正确姿势
  4. linux电脑合盖后卡住了,解决ubuntu合盖后无法唤醒
  5. ES6/05/正则表达式简介,正则表达式如何使用,正则表达式中的特殊字符(边界符,量词符),预定义类,正则表达式中的替换
  6. Mathpix图片转LaTeX,Word快速插入LaTeX公式教程
  7. 操作系统文件管理_计算机民科笔记-操作系统week1
  8. gitlab版本控制系统源码部署
  9. 深度学习系列--1.入坑模型: 线性回归,logistic 回归,softmax分类器
  10. 一次library cache pin故障的解决过程
  11. 【算法笔记】图文结合彻底搞懂后缀数组
  12. STM32串口接收以及发送大全
  13. weblogic安装部署linux下
  14. html页面显示不全问题,网页显示不完全
  15. 矩阵和POJ 3233
  16. Dubbo之手写RPC框架
  17. 这五款小众软件你肯定不知道
  18. python算程序员吗_2019为什么有人说Python程序员是假的程序员?
  19. java输入值按回车下一个_java 如何 按回车 光标换到下个输入框
  20. Python小游戏--数字“炸弹“

热门文章

  1. 公司的高管,每天都在做什么?
  2. 怎样让一个心浮气躁的孩子静下心学习?
  3. 养一辆最新的奥迪Q7一年要花费多少钱?
  4. 有些新手小白创业者开奶茶店,为什么总是容易上当受骗呢?
  5. 经常有职场上的朋友问我,要怎么去轻资产创业?
  6. IT程序员们平时都喜欢逛什么论坛呢?
  7. linux amp;amp; ; amp;amp;amp;amp; ||
  8. Navicat常用快捷键
  9. win7php一键,批处理也能干大事之——如何实现Win7系统一键切换用户
  10. 如何查找数据库服务器ip_多服务器管理–查找数据库服务器