Codevs 2460 == BZOJ 1036 树的统计
2460 树的统计
2008年省队选拔赛浙江
一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w。
我们将以下面的形式来要求你对这棵树完成一些操作:
- I. CHANGE u t : 把结点u的权值改为t
- II. QMAX u v: 询问从点u到点v的路径上的节点的最大权值
- III. QSUM u v: 询问从点u到点v的路径上的节点的权值和
注意:从点u到点v的路径上的节点包括u和v本身
输入文件的第一行为一个整数n,表示节点的个数。
接下来n – 1行,每行2个整数a和b,表示节点a和节点b之间有一条边相连。
接下来n行,每行一个整数,第i行的整数wi表示节点i的权值。
接下来1行,为一个整数q,表示操作的总数。
接下来q行,每行一个操作,以“CHANGE u t”或者“QMAX u v”或者“QSUM u v”的形式给出。
对于每个“QMAX”或者“QSUM”的操作,每行输出一个整数表示要求输出的结果。
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
4
1
2
2
10
6
5
6
5
16
对于100%的数据,保证1<=n<=30000,0<=q<=200000;中途操作中保证每个节点的权值w在-30000到30000之间。
#include<iostream>
#include<cstdio>
#include<cstring>
#define maxn 300001
using namespace std;
int head[maxn],dep[maxn],fa[maxn],a[maxn];
int pos[maxn],top[maxn],size[maxn],son[maxn];
int tot,n,m,cnt,maxsize,x,y,num;
struct Edge{int next,to;}e[maxn<<];
struct Node{int l,r,max,sum;}tre[maxn<<];
int read(){
int x=,f=;char c=getchar();
while(c<''||c>''){if(c=='-')f=-;c=getchar();}
while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
return x*f;
}
int max(int a,int b){if(a>b)return a;else return b;}
void Add_Edge(int u,int v){
e[++num].to=v;e[num].next=head[u];head[u]=num;
}
void DFS_First(int now,int pre,int deepth){
dep[now] = deepth; fa[now] = pre; size[now] = ;
for(int i=head[now];i;i=e[i].next){
int v=e[i].to;
if(v!=pre){
DFS_First(v,now,deepth+);
size[now] += size[v];
if(son[now]==-||size[v]>size[son[now]])
son[now]=v;
}
}
}
void Get_Pos(int u,int Top){
int k=;maxsize++;
pos[u]=maxsize;top[u]=Top;
if(!son[u])return;
Get_Pos(son[u],Top);
for(int i=head[u];i;i=e[i].next)
if(dep[e[i].to]>dep[u]&&e[i].to!=son[u])
Get_Pos(e[i].to,e[i].to);
return;
}
void Build(int now,int l,int r){
tre[now].l=l;tre[now].r=r;
if(l==r){
tre[now].sum=tre[now].max=;return ;
}
int mid=(l+r)>>;
Build(now<<,l,mid);Build(now<<|,mid+,r);
tre[now].sum=tre[now<<].sum+tre[now<<|].sum;
tre[now].max=max(tre[now<<].max,tre[now<<|].max); }
void Insert(int now,int poss,int val){
if(tre[now].l==tre[now].r){
tre[now].sum=tre[now].max=val;return;
}
int mid=(tre[now].l+tre[now].r)/;
if(poss<=mid)Insert(now<<,poss,val);
else if(poss>mid)Insert(now<<|,poss,val);
tre[now].sum=tre[now<<].sum+tre[now<<|].sum;
tre[now].max=max(tre[now<<].max,tre[now<<|].max);
}
int QueryMax(int now,int l,int r){
if(l<=tre[now].l&&tre[now].r<=r)return tre[now].max;
int mid=(tre[now].l+tre[now].r)>>,total=-1e9;
if(l<=mid)total=max(total,QueryMax(now<<,l,r));
if(r>mid)total=max(total,QueryMax(now<<|,l,r));
return total;
}
int QuerySum(int now,int l,int r){
if(l<=tre[now].l&&tre[now].r<=r)return tre[now].sum;
int mid=(tre[now].l+tre[now].r)>>,total=;
if(l<=mid)total+=QuerySum(now<<,l,r);
if(r>mid)total+=QuerySum(now<<|,l,r);
return total;
}
int SolveMax(int u,int v){
int ans=-1e9;
while(top[u]!=top[v]){
if(dep[top[u]]<dep[top[v]])swap(u,v);
ans=max(ans,QueryMax(,pos[top[u]],pos[u]));
u=fa[top[u]];
}
if(pos[u]>pos[v]) swap(u,v);
ans=max(ans,QueryMax(,pos[u],pos[v]));
return ans;
}
int SolveSum(int u,int v){
int ans=;
while(top[u]!=top[v]){
if(dep[top[u]]<dep[top[v]])swap(u,v);
ans+=QuerySum(,pos[top[u]],pos[u]);
u=fa[top[u]];
}
if(pos[u]>pos[v])swap(u,v);
ans+=QuerySum(,pos[u],pos[v]);
return ans;
}
int main(){
n=read();
for(int i=;i<n;i++){
x=read();y=read();
Add_Edge(x,y);Add_Edge(y,x);
}
for(int i=;i<=n;i++) a[i]=read();
DFS_First(,,);
Get_Pos(,);
Build(,,maxsize);
for(int i=;i<=n;i++)
Insert(,pos[i],a[i]);
m=read();char sp[];
while(m--){
scanf("%s",sp);scanf("%d%d",&x,&y);
if(sp[]=='C')a[x]=y,Insert(,pos[x],y);
else{
if(sp[]=='M') printf("%d\n",SolveMax(x,y));
else printf("%d\n",SolveSum(x,y));
}
}
return ;
}
Codevs 2460 == BZOJ 1036 树的统计的更多相关文章
- BZOJ 1036 树的统计-树链剖分
[ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 12904 Solved: 5191[Submit][Status ...
- BZOJ 1036 树的统计
Description 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把结点u的权值改为t II. Q ...
- BZOJ 1036 树的统计Count 树链剖分模板题
题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=1036 题目大意: 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将 ...
- [置顶] bzoj 1036 树的统计Count 点权值模板
树链剖分 点权型可做模板,链路剖分的思想把点hash到线段树的上,然后可通过n*(log(n)*log(n))的复杂度在树上操作,在线段树上能操作的在链路上都能操作. #include<cstd ...
- BZOJ 1036 树的统计(树链剖分)
点权树链剖分模板题. # include <cstdio> # include <cstring> # include <cstdlib> # include &l ...
- bzoj 1036 树的统计Count
题目大意: 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w 我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把结点u的权值改为t II. QMAX u ...
- BZOJ - 1036 树的统计Count (LCT)
LCT试炼题(代码量居然完爆树剖?) #include<bits/stdc++.h> using namespace std; ,inf=0x3f3f3f3f; ],flp[N],n,m, ...
- Bzoj 1036 树的统计 分类: ACM TYPE 2014-12-29 18:55 72人阅读 评论(0) 收藏
Description 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把结点u的权值改为t II. Q ...
- BZOJ 1036 树的统计 | 树链剖分模板题
又做了一遍--去掉读入优化只有八十行~ #include <cstdio> #include <cstring> #include <algorithm> usin ...
随机推荐
- 列举Asp.net页面之间传递值的几种方式和优缺点?
一.QueryString变量 优点:使用简单,对于安全性要求不高时传递数字或是文本值非常有效. 缺点:缺乏安全性,由于它的值暴露在浏览器的URL地址中的:不能传递对象. 二. 使用Applicati ...
- 原生node实现本地静态页面的展示
var http = require("http"); var fs = require("fs"); var url = require("url& ...
- php五种常见的设计模式
工厂模式 工厂模式是最常用的实例化对象的模式,是用工厂方法代替new操作的一种模式 使用工厂模式的好处是:如果想要更改实例化的类名,则只需要更改该工厂方法内容即可,不需逐一寻找代码中具体实例化的地方( ...
- 常用模块之 re shutil configparser hashlib xldt和xlwd
shutil 高级文件处理模块 封装的更简单了 主要是文件的复制,移动,压缩解压缩 需要保证目标文件已经存在shutil.copymode('test.txt','testcopy4.txt') 压缩 ...
- 51nod_1459 最短路 dijkstra 特调参数
好多基础知识都没补完,只好看到.用到一个赶紧补全一个,并且保证下次需要的时候直接用,不用回来再补: 其实这个算法是在补同余最短路的时候用到的,当时突然发现理解算法导论上的原理甚至有效性证明,但是就是没 ...
- 第三模块 面向对象& 网络编程基础 实战考核
1.简述构造方法和析构方法. 构造方法(__init__):主要作用是实例化时给实例一些初始化参数,或执行一些其它的初始化工作,总之因为这个__init__只要一实例化, 就会自动执行,不管你在这个方 ...
- Python+Selenium练习篇之5-利用partial link text定位元素
本文介绍如何通过partial link text来定位页面元素.看到这个,有点和前一篇文字link text有点类似.字面意思,确实和link text相类似,partial link text就是 ...
- 混淆矩阵、准确率、召回率、ROC曲线、AUC
混淆矩阵.准确率.召回率.ROC曲线.AUC 假设有一个用来对猫(cats).狗(dogs).兔子(rabbits)进行分类的系统,混淆矩阵就是为了进一步分析性能而对该算法测试结果做出的总结.假设总共 ...
- c# 操作access数据库image ole字段
using System; using System.Data; using System.Configuration; using System.Web; using System.Data.Ole ...
- maven学习(十五)——在eclipse中使用maven创建javaweb项目
一.创建Web项目 1.1 选择建立Maven Project 选择File -> New ->Project,如下图所示: