【ZJOI2008】树的统计
题目
一棵树上有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本身
分析
只用单点修改的树链剖分模板题。
#include <cmath>
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <queue>
const int maxlongint=2147483647;
using namespace std;
struct trees
{
int v,mx,l,r;
}tree[90000];
int d[90000],dson[90000],deep[90000],size[90000],fa[90000],top[90000],n,m,v[90000],bef[90000],tot,mi2[30];
int next[90000],last[90000],to[90000],po;
int ans;
int bj(int x,int y)
{
next[++tot]=last[x];
last[x]=tot;
to[tot]=y;
}
int dg(int x)
{
size[x]=1;
int mx=0;
for(int i=last[x];i;i=next[i])
{
if(to[i]!=fa[x])
{
fa[to[i]]=x;
deep[to[i]]=deep[x]+1;
dg(to[i]);
size[x]+=size[to[i]];
if(size[to[i]]>mx)
{
mx=size[to[i]];
dson[x]=to[i];
}
}
}
}
int dg1(int x)
{
bef[x]=++tot;
d[tot]=x;
if(top[x]==0)
{
top[x]=x;
}
if(dson[x])
{
top[dson[x]]=top[x];
dg1(dson[x]);
}
for(int i=last[x];i;i=next[i])
{
if(to[i]!=fa[x] && to[i]!=dson[x])
{
dg1(to[i]);
}
}
}
int treechange(int l,int r,int pos,int aim,int value)
{
int mid=(l+r)/2;
tree[pos].l=l;
tree[pos].r=r;
if(l==r)
{
tree[pos].v=value;
tree[pos].mx=value;
return 0;
}
if(aim<=mid)
{
treechange(l,mid,pos*2,aim,value);
}
else
{
treechange(mid+1,r,pos*2+1,aim,value);
}
tree[pos].v=tree[pos*2].v+tree[pos*2+1].v;
tree[pos].mx=max(tree[pos*2].mx,tree[pos*2+1].mx);
}
int findmx(int l,int r,int pos,int aiml,int aimr)
{
int mid=(l+r)/2;
if(l==aiml && r==aimr)
{
ans=max(ans,tree[pos].mx);
return 0;
}
if(aimr<=mid)
{
findmx(l,mid,pos*2,aiml,aimr);
}
else
if(aiml>mid)
{
findmx(mid+1,r,pos*2+1,aiml,aimr);
}
else
{
findmx(l,mid,pos*2,aiml,mid);
findmx(mid+1,r,pos*2+1,mid+1,aimr);
}
}
int findmax(int x,int y)
{
ans=-maxlongint;
while(top[x]!=top[y])
{
if(deep[top[x]]>=deep[top[y]])
{
findmx(1,n,1,bef[top[x]],bef[x]);
x=fa[top[x]];
}
else
{
findmx(1,n,1,bef[top[y]],bef[y]);
y=fa[top[y]];
}
}
if(deep[x]>=deep[y])
{
findmx(1,n,1,bef[y],bef[x]);
}
else
{
findmx(1,n,1,bef[x],bef[y]);
}
printf("%d\n",ans);
}
int findsm(int l,int r,int pos,int aiml,int aimr)
{
int mid=(l+r)/2;
if(l==aiml && r==aimr)
{
ans+=tree[pos].v;
return 0;
}
if(aimr<=mid)
{
findsm(l,mid,pos*2,aiml,aimr);
}
else
if(aiml>mid)
{
findsm(mid+1,r,pos*2+1,aiml,aimr);
}
else
{
findsm(l,mid,pos*2,aiml,mid);
findsm(mid+1,r,pos*2+1,mid+1,aimr);
}
}
int findsum(int x,int y)
{
ans=0;
while(top[x]!=top[y])
{
if(deep[top[x]]>=deep[top[y]])
{
findsm(1,n,1,bef[top[x]],bef[x]);
x=fa[top[x]];
}
else
{
findsm(1,n,1,bef[top[y]],bef[y]);
y=fa[top[y]];
}
}
if(deep[x]>=deep[y])
{
findsm(1,n,1,bef[y],bef[x]);
}
else
{
findsm(1,n,1,bef[x],bef[y]);
}
printf("%d\n",ans);
}
int main()
{
mi2[1]=1;
for(int i=2;i<=25;i++)
mi2[i]=mi2[i-1]*2;
scanf("%d",&n);
for(int i=1;i<=n-1;i++)
{
int x,y;
scanf("%d%d",&x,&y);
bj(x,y);
bj(y,x);
}
deep[1]=1;
dg(1);
tot=0;
dg1(1);
for(int i=1;i<=90000-1;i++)
tree[i].mx=-maxlongint;
for(int i=1;i<=25;i++)
{
if(mi2[i]*2>=tot)
{
po=mi2[i]*2-1;
break;
}
}
for(int i=1;i<=n;i++)
{
int x;
scanf("%d",&x);
treechange(1,n,1,bef[i],x);
}
scanf("%d\n",&m);
char c;
for(int i=1;i<=m;i++)
{
c=getchar();
if(c=='C')
{
int x,y;
scanf("HANGE %d %d\n",&x,&y);
treechange(1,n,1,bef[x],y);
}
else
{
c=getchar();
if(c=='M')
{
int x,y;
scanf("AX %d %d\n",&x,&y);
findmax(x,y);
}
else
{
int x,y;
scanf("UM %d %d\n",&x,&y);
findsum(x,y);
}
}
}
}
【ZJOI2008】树的统计的更多相关文章
- BZOJ 1036: [ZJOI2008]树的统计Count [树链剖分]【学习笔记】
1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 14302 Solved: 5779[Submit ...
- bzoj1036 [ZJOI2008]树的统计Count
1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MB Submit: 12646 Solved: 5085 [Subm ...
- BZOJ 1036: [ZJOI2008]树的统计Count
1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MB Submit: 14354 Solved: 5802 [Subm ...
- 【BZOJ1036】[ZJOI2008]树的统计Count 树链剖分
[BZOJ1036][ZJOI2008]树的统计Count Description 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将以下面的形式来要求你对这棵树完成一些操作: I. ...
- bzoj 1036 [ZJOI2008]树的统计Count(树链剖分,线段树)
1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 10677 Solved: 4313[Submit ...
- Bzoj 1036: [ZJOI2008]树的统计Count 树链剖分,LCT
1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 11102 Solved: 4490[Submit ...
- 数据结构(LCT动态树):BZOJ 1036: [ZJOI2008]树的统计Count
1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 12266 Solved: 4945[Submit ...
- BZOJ 1036: [ZJOI2008]树的统计Count( 树链剖分 )
树链剖分... 不知道为什么跑这么慢 = = 调了一节课啊跪.. ------------------------------------------------------------------- ...
- 1036: [ZJOI2008]树的统计Count
1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 7496 Solved: 3078[Submit] ...
- bzoj1036 [ZJOI2008]树的统计Count 树链剖分模板题
[ZJOI2008]树的统计Count Description 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将以下面的形式来要求你对这棵树完成 一些操作: I. CHANGE u ...
随机推荐
- 系统分析与设计HW2
简答题 1. 简述瀑布模型.增量模型.螺旋模型(含原型方法)的优缺点. 瀑布模型 优点: 定义了软件开发基本流程与活动. 为项目提供了按阶段划分的检查点. 当前一阶段完成后,只需关注后续阶段. 缺点: ...
- Gradle之Android Gradle Plugin 主要流程分析(二)
[Android 修炼手册]Gradle 篇 -- Android Gradle Plugin 主要流程分析 预备知识 理解 gradle 的基本开发 了解 gradle task 和 plugin ...
- Oracle 启用登录终端超时锁定功能
远程连接oracle 会出现超时连接断开的问题,所以需要修改oracle配置. 修改超时时间10分钟 ALTER PROFILE DEFAULT LIMIT IDLE_TIME 10; 查询修改后的超 ...
- 终极Shell - Oh My Zsh
介绍 zsh: 与 bash 同为 shell 软件,适用于 linux 和 mac,mac 与百度开发机已自带. oh-my-zsh:zsh 的一个开源配置方案,即下即用,免去复杂的配置过程.配置后 ...
- c++ 创建 uuid guid
如果没安装,先安装: [root@localhost]# yum install libuuid-devel #include "uuid/uuid.h" 引用 libuuid.s ...
- mysql驱动表与被驱动表及join优化
驱动表与被驱动表 先了解在join连接时哪个表是驱动表,哪个表是被驱动表:1.当使用left join时,左表是驱动表,右表是被驱动表2.当使用right join时,右表时驱动表,左表是驱动表3.当 ...
- 第十三周学习总结 Java的异常
java的核心思想 面向对象的编程思想 类和类的关系 类中成员的描述 对象创建 Java工具类 包装类 数学相关 日期相关 字符串相关 集合相关的类 考试机 学生 老师 --------------- ...
- [DS+Algo] 010 二叉树的遍历
二叉树遍历 深度优先 一般用递归 一些名词 遍历方式 英文 先序 Preorder 中序 Inorder 后序 Postorder 广度优先 一般用队列 Python 代码示例 class Node( ...
- linux:shell脚本格式
shell脚本格式: #!/bin/bash //第一行指定bash 命令群..... 例子: #!/bin/bash DESCDIR='/tmp/t ...
- 在SQL中存储过程的一般语法
一般分为十种情况,每种语法各不相同: 1. 创建语法 1 2 3 4 5 6 7 create proc | procedure pro_name [{@参数数据类型} [=默认值] [outp ...