Bzoj 1036: [ZJOI2008]树的统计Count 树链剖分,LCT
1036: [ZJOI2008]树的统计Count
Time Limit: 10 Sec Memory Limit: 162 MB
Submit: 11102 Solved: 4490
[Submit][Status][Discuss]
Description
一棵树上有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本身
Input
输入的第一行为一个整数n,表示节点的个数。接下来n – 1行,每行2个整数a和b,表示节点a和节点b之间有一条边相连。接下来n行,每行一个整数,第i行的整数wi表示节点i的权值。接下来1行,为一个整数q,表示操作的总数。接下来q行,每行一个操作,以“CHANGE u t”或者“QMAX u v”或者“QSUM u v”的形式给出。 对于100%的数据,保证1<=n<=30000,0<=q<=200000;中途操作中保证每个节点的权值w在-30000到30000之间。
Output
对于每个“QMAX”或者“QSUM”的操作,每行输出一个整数表示要求输出的结果。
Sample Input
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
1
2
2
10
6
5
6
5
16
HINT
Source
#include<bits/stdc++.h>
using namespace std;
#define lson k*2,l,mid
#define rson k*2+1,mid+1,r
#define MAXN 30010
#define INF 1e9
struct node
{
int begin,end,next;
}edge[MAXN*];
struct NODE
{
int left,right,sum,mx,val;
}tree[*MAXN];
int cnt,Head[MAXN],val[MAXN],deep[MAXN],size[MAXN],P[MAXN][],belong[MAXN],pos[MAXN],SIZE,n;
bool vis[MAXN];
void addedge(int bb,int ee)
{
edge[++cnt].begin=bb;edge[cnt].end=ee;edge[cnt].next=Head[bb];Head[bb]=cnt;
}
void addedge1(int bb,int ee)
{
addedge(bb,ee);addedge(ee,bb);
}
int read()
{
int s=,fh=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')fh=-;ch=getchar();}
while(ch>=''&&ch<=''){s=s*+(ch-'');ch=getchar();}
return s*fh;
}
void dfs1(int u)
{
int i,v;
size[u]=;vis[u]=true;
for(i=Head[u];i!=-;i=edge[i].next)
{
v=edge[i].end;
if(vis[v]==false)
{
deep[v]=deep[u]+;
P[v][]=u;
dfs1(v);
size[u]+=size[v];
}
}
}
void Ycl()
{
int i,j;
for(j=;(<<j)<=n;j++)
{
for(i=;i<=n;i++)
{
if(P[i][j-]!=-)P[i][j]=P[P[i][j-]][j-];
}
}
}
void dfs2(int u,int chain)
{
int k=,i,v;
pos[u]=++SIZE;belong[u]=chain;
for(i=Head[u];i!=-;i=edge[i].next)
{
v=edge[i].end;
if(deep[v]>deep[u]&&size[v]>size[k])k=v;
}
if(k==)return;
dfs2(k,chain);
for(i=Head[u];i!=-;i=edge[i].next)
{
v=edge[i].end;
if(deep[v]>deep[u]&&v!=k)dfs2(v,v);
}
}
int LCA(int x,int y)
{
int i,j;
if(deep[x]<deep[y])swap(x,y);
for(i=;(<<i)<=deep[x];i++);i--;
for(j=i;j>=;j--)if(deep[x]-(<<j)>=deep[y])x=P[x][j];
if(x==y)return x;
for(j=i;j>=;j--)
{
if(P[x][j]!=-&&P[x][j]!=P[y][j])
{
x=P[x][j];
y=P[y][j];
}
}
return P[x][];
}
void Pushup(int k)
{
tree[k].sum=tree[k*].sum+tree[k*+].sum;
tree[k].mx=max(tree[k*].mx,tree[k*+].mx);
}
void Build(int k,int l,int r)
{
tree[k].left=l;tree[k].right=r;
if(l==r)return;
int mid=(l+r)/;
Build(lson);
Build(rson);
}
void Change(int k,int P,int V)
{
if(tree[k].left==tree[k].right)
{
tree[k].val=tree[k].sum=tree[k].mx=V;
return;
}
int mid=(tree[k].left+tree[k].right)/;
if(P<=mid)Change(k*,P,V);
else Change(k*+,P,V);
Pushup(k);
}
int Query_max(int k,int l,int r)
{
if(l<=tree[k].left&&tree[k].right<=r)return tree[k].mx;
int mid=(tree[k].left+tree[k].right)/;
if(r<=mid)return Query_max(k*,l,r);
else if(l>mid)return Query_max(k*+,l,r);
else return max(Query_max(k*,l,mid),Query_max(k*+,mid+,r));
}
int Query_sum(int k,int l,int r)
{
if(l<=tree[k].left&&tree[k].right<=r)return tree[k].sum;
int mid=(tree[k].left+tree[k].right)/;
if(r<=mid)return Query_sum(k*,l,r);
else if(l>mid)return Query_sum(k*+,l,r);
else return Query_sum(k*,l,mid)+Query_sum(k*+,mid+,r);
}
int solve_max(int x,int f)
{
int MAX=-INF;
while(belong[x]!=belong[f])
{
MAX=max(MAX,Query_max(,pos[belong[x]],pos[x]));
x=P[belong[x]][];
}
MAX=max(MAX,Query_max(,pos[f],pos[x]));
return MAX;
}
int solve_sum(int x,int f)
{
int SUM=;
while(belong[x]!=belong[f])
{
SUM+=Query_sum(,pos[belong[x]],pos[x]);
x=P[belong[x]][];
}
SUM+=Query_sum(,pos[f],pos[x]);
return SUM;
}
int main()
{
freopen("bzoj_1036.in","r",stdin);
freopen("bzoj_1036.out","w",stdout);
int m,i,bb,ee,u,v,t,lca;
char zs[];
n=read();
memset(Head,-,sizeof(Head));cnt=;
for(i=;i<n;i++)
{
bb=read();ee=read();addedge1(bb,ee);
}
memset(P,-,sizeof(P));SIZE=;
dfs1();Ycl();
dfs2(,);
for(i=;i<=n;i++)val[i]=read();
Build(,,n);
for(i=;i<=n;i++)Change(,pos[i],val[i]);
m=read();
for(i=;i<=m;i++)
{
scanf("\n%s",zs);
if(zs[]=='C'){u=read();t=read();val[u]=t;Change(,pos[u],val[u]);}
else
{
if(zs[]=='M')
{
u=read();v=read();
lca=LCA(u,v);
printf("%d\n",max(solve_max(u,lca),solve_max(v,lca)));
}
else {u=read();v=read();lca=LCA(u,v);printf("%d\n",solve_sum(u,lca)+solve_sum(v,lca)-val[lca]);}
}
}
fclose(stdin);
fclose(stdout);
return ;
}
Bzoj 1036: [ZJOI2008]树的统计Count 树链剖分,LCT的更多相关文章
- BZOJ 1036: [ZJOI2008]树的统计Count [树链剖分]【学习笔记】
1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 14302 Solved: 5779[Submit ...
- BZOJ 1036: [ZJOI2008]树的统计Count( 树链剖分 )
树链剖分... 不知道为什么跑这么慢 = = 调了一节课啊跪.. ------------------------------------------------------------------- ...
- bzoj 1036: [ZJOI2008]树的统计Count 树链剖分+线段树
1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 16294 Solved: 6645[Submit ...
- BZOJ 1036: [ZJOI2008]树的统计Count (树链剖分模板题)
1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 14982 Solved: 6081[Submit ...
- BZOJ 1036 [ZJOI2008]树的统计Count (树链剖分)(线段树单点修改)
[ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 14968 Solved: 6079[Submit][Stat ...
- 【BZOJ1036】[ZJOI2008]树的统计Count 树链剖分
[BZOJ1036][ZJOI2008]树的统计Count Description 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将以下面的形式来要求你对这棵树完成一些操作: I. ...
- bzoj1036 [ZJOI2008]树的统计Count 树链剖分模板题
[ZJOI2008]树的统计Count Description 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将以下面的形式来要求你对这棵树完成 一些操作: I. CHANGE u ...
- Cogs 1688. [ZJOI2008]树的统计Count(树链剖分+线段树||LCT)
[ZJOI2008]树的统计Count ★★★ 输入文件:bzoj_1036.in 输出文件:bzoj_1036.out 简单对比 时间限制:5 s 内存限制:162 MB [题目描述] 一棵树上有n ...
- BZOJ 1036 [ZJOI2008]树的统计Count (树链剖分 - 点权剖分 - 单点权修改)
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1036 树链剖分模版题,打的时候注意点就行.做这题的时候,真的傻了,单词拼错检查了一个多小时 ...
随机推荐
- /var子目录
/var子目录 目录 描述 /var/log/message 日志信息,按周自动轮询 /var/spool/cron/root 定时器配置文件目录,默认按用户命名 /var/log/secure 记录 ...
- Oracle 10g 下载地址
Oracle Database 10g Release 2 (10.2.0.1.0) Enterprise/Standard Edition for Microsoft Windows (32-bit ...
- C#实现JSON序列化与反序列化介绍
方法一:引入System.Web.Script.Serialization命名空间使用 JavaScriptSerializer类实现简单的序列化 序列化类:Personnel public clas ...
- php对象的高级特性
对象比较,当同一个类的两个实例的所有属性都相等时,可以使用比较运算符==进行判断,当需要判断两个变量是否为同一个对象的引用时,可以使用全等运算符===进行判断. class Car { } $a = ...
- linux 下C语言编程库文件处理与Makefile编写
做开发快3年了,在linux下编译安装软件算是家常便饭了.就拿gcc来说,都有不下10次了,可基本每次都会碰到些奇奇怪怪的问题.看来还是像vs.codeblocks这样的ide把人弄蠢了.便下定决心一 ...
- Sublime Text 3 LESS、SASS、SCSS高亮插件、提示插件
为sublime text 添加LESS语法高亮 功能:LESS高亮插件 下载 https://packagecontrol.io/packages/LESS 简介:用LESS的同学都知道,s ...
- NET笔记——Delegate
对于初学者,委托是很容易让人晕的,一是晕它如何起作用,二是晕它有什么用. 最近回过头来又看了下委托,又有些不同的感觉,写之自用. 声明方面,委托可以被声明在类内,也可以与类同级,并且声明时没有方法体: ...
- C/S和B/S两种软件体系结构
目前两种流行的软件体系结构就是C/S和B/S体系结构,下面对两种体系结构进行一下总结: 1.C/S(客户端/服务器模式): 客户端和服务器都是独立的计算机,客户端是面向最终用户的应用程序或一些接口设备 ...
- Hibernate学习笔记--环境搭建及运行
1.hibernate开发包下载 http://sourceforge.net/projects/hibernate/files/ 如果不能访问请用代理http://dongtaiwang.com/l ...
- 三点经验:长时间运行函数需要随时发射信号报告进度,以及设置bool变量随时可以退出,每做一步操作必须及时记录和处理相关信息
三点经验:长时间运行函数需要随时发射信号报告进度,以及设置bool变量随时可以退出,每做一步操作必须及时记录和处理相关信息 不能到最后一起处理,否则万一中间出错了,这个记录状态就全部都乱了.