「ZJOI2008」「LuoguP2590」树的统计(树链剖分
题目描述
一棵树上有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之间。
题解
先剖一下。
CHANGE:把dfn[x]处改为t
然后线段树同时维护两个值:mac(区间内最大值)和sum(区间和)
在修改的时候,先递归到叶子节点,然后在回溯的同时维护mac和sum,单次复杂度logn。
就星了。
/*
qwerta
P2590 [ZJOI2008]树的统计
Accepted
100
代码 C++,3.62KB
提交时间 2018-09-11 19:18:59
耗时/内存
3536ms, 6424KB
*/
#include<cmath>
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
#define R register
#define LL long long
inline int read()
{
char ch=getchar();
int x=;bool s=;
while(ch<''||ch>''){if(ch=='-')s=;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return s?x:-x;
}
const int MAXN=+;
struct emm{
int e,f;
}b[*MAXN];
int h[MAXN];
int tot=;
void con(int x,int y)
{
b[++tot].f=h[x];
h[x]=tot;
b[tot].e=y;
b[++tot].f=h[y];
h[y]=tot;
b[tot].e=x;
return;
}
int s;
int d[MAXN],fa[MAXN],top[MAXN],siz[MAXN],z[MAXN];
void dfs(int x)
{
siz[x]=,top[x]=x;
int mac=,macc=-;
for(int i=h[x];i;i=b[i].f)
if(!d[b[i].e])
{
d[b[i].e]=d[x]+;
fa[b[i].e]=x;
dfs(b[i].e);
siz[x]+=siz[b[i].e];
if(macc<siz[b[i].e]){mac=b[i].e,macc=siz[b[i].e];}
}
z[x]=mac;
top[mac]=x;
return;
}
int q[MAXN],dfn[MAXN];
void dfss(int x)
{
q[++tot]=x;
dfn[x]=tot;
if(z[x])dfss(z[x]);
for(int i=h[x];i;i=b[i].f)
if(fa[b[i].e]==x&&b[i].e!=z[x])
dfss(b[i].e);
return;
}
int fitop(int x)
{
if(top[x]==x)return x;
return top[x]=fitop(top[x]);
}
int val[MAXN];
struct ahh{
int l,r,mid,mac;
long long sum;
}a[*MAXN];
#define lz (i<<1)
#define rz ((i<<1)|1)
#define md a[i].mid
void build(int i,int ll,int rr)
{
a[i].l=ll;
a[i].r=rr;
if(ll==rr){a[i].mac=a[i].sum=val[q[ll]];return;}
md=(ll+rr)>>;
build(lz,ll,md);
build(rz,md+,rr);
a[i].mac=max(a[lz].mac,a[rz].mac);
a[i].sum=a[lz].sum+a[rz].sum;
return;
}
void change(int i,int x,int k)
{
if(a[i].l==a[i].r){a[i].mac=a[i].sum=k;return;}
if(x<=md)change(lz,x,k);
else change(rz,x,k);
a[i].mac=max(a[lz].mac,a[rz].mac);
a[i].sum=a[lz].sum+a[rz].sum;
return;
}
long long ans;
void findmac(int i,int ll,int rr)
{
if(a[i].l==ll&&a[i].r==rr){if(a[i].mac>ans)ans=a[i].mac;return;}
if(rr<=md)findmac(lz,ll,rr);
else if(md+<=ll)findmac(rz,ll,rr);
else {findmac(lz,ll,md);findmac(rz,md+,rr);}
return;
}
void findsum(int i,int ll,int rr)
{
if(a[i].l==ll&&a[i].r==rr){ans+=a[i].sum;return;}
if(rr<=md)findsum(lz,ll,rr);
else if(md+<=ll)findsum(rz,ll,rr);
else {findsum(lz,ll,md);findsum(rz,md+,rr);}
return;
}
int main()
{
//freopen("a.in","r",stdin);
int n;
cin>>n;
for(int i=;i<n;++i)
{
int u,v;
cin>>u>>v;
con(u,v);
}
s=min(,n);
d[s]=;
dfs(s);
tot=;
dfss(s);
for(int i=;i<=n;++i)
top[i]=fitop(i);
for(int i=;i<=n;++i)
cin>>val[i];
build(,,n);
int q;
cin>>q;
for(int i=;i<=q;++i)
{
string st;
cin>>st;
if(st[]=='C')
{
int u,t;
cin>>u>>t;
change(,dfn[u],t);
}
else if(st[]=='M')
{
int u,v;
cin>>u>>v;
ans=-;
while(top[u]!=top[v])
{
if(d[top[u]]<d[top[v]])swap(u,v);
findmac(,dfn[top[u]],dfn[u]);
u=fa[top[u]];
}
if(d[u]<d[v])swap(u,v);
findmac(,dfn[v],dfn[u]);
cout<<ans<<endl;
}
else
{
int u,v;
cin>>u>>v;
ans=;
while(top[u]!=top[v])
{
if(d[top[u]]<d[top[v]])swap(u,v);
findsum(,dfn[top[u]],dfn[u]);
u=fa[top[u]];
}
if(d[u]<d[v])swap(u,v);
findsum(,dfn[v],dfn[u]);
cout<<ans<<endl;
}
}
return ;
}
「ZJOI2008」「LuoguP2590」树的统计(树链剖分的更多相关文章
- BZOJ 1036: [ZJOI2008]树的统计Count-树链剖分(点权)(单点更新、路径节点最值、路径求和)模板,超级认真写了注释啊啊啊
1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 23015 Solved: 9336[Submit ...
- 树的统计Count---树链剖分
NEFU专项训练十和十一——树链剖分 Description 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t ...
- luoguP2590 [ZJOI2008]树的统计(树链剖分)
luogu P2590 [ZJOI2008]树的统计 题目 #include<iostream> #include<cstdlib> #include<cstdio> ...
- BZOJ1036[ZJOI2008]树的统计——树链剖分+线段树
题目描述 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把结点u的权值改为t II. QMAX u v ...
- 洛谷P2590 [ZJOI2008] 树的统计 [树链剖分]
题目传送门 树的统计 题目描述 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w. 我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把结点u的权值改为t ...
- [ZJOI2008]树的统计——树链剖分
本题是一个树链剖分裸题,由于比较菜,老是RE,后来发现是因为使用了全局变量. /************************************************************ ...
- [luogu P2590 ZJOI2008] 树的统计 (树链剖分)
题目描述 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w. 我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把结点u的权值改为t II. QMAX u ...
- BZOJ-1036 树的统计Count 链剖线段树(模板)=(树链剖分+线段树)
潇爷昨天刚刚讲完...感觉得还可以...对着模板打了个模板...还是不喜欢用指针.... 1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Lim ...
- BZOJ 1036 树的统计-树链剖分
[ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 12904 Solved: 5191[Submit][Status ...
- [LOJ3014][JOI 2019 Final]独特的城市——树的直径+长链剖分
题目链接: [JOI 2019 Final]独特的城市 对于每个点,它的答案最大就是与它距离最远的点的距离. 而如果与它距离为$x$的点有大于等于两个,那么与它距离小于等于$x$的点都不会被计入答案. ...
随机推荐
- [Inside HotSpot] Serial垃圾回收器 (二) Minor GC
Serial垃圾回收器Minor GC 1. DefNewGeneration垃圾回收 新生代使用复制算法做垃圾回收,比老年代的标记-压缩简单很多,所有回收代码都位于DefNewGeneration: ...
- 大整数类BIGN的设计与实现 C++高精度模板
首先感谢刘汝佳所著的<算法竞赛入门经典>. 众所周知,C++中储存能力最大的unsigned long long 也是有着一个上限,如果我们想计算非常大的整数时,就不知所措了,所以,我写了 ...
- 5.JAVA语言基础部分—多线程
一个应用有一个进程,一个进程里可以用多个线程 1)定义 定义线程有两种方式,一是继承java.lang.Thread类,二是实现java.lang.Runnable接口.其实Thread类就是实现了R ...
- OD调试器调试Delphi程序按钮事件断点方法
这几天我调试一个Delphi程序,总是无法断点按钮事件,像我这样的菜鸟断点按钮事件真心累啊.所以我分享一下我下断点的经验!希望新手们少走弯路!! 工具/原料 OD调试器 Delphi程序 方法 ...
- 【Todo】已经打开的页面需要清掉的坑
下面是当前我浏览器里面打开的技术文章.需要清掉.一个坑一个坑地填吧. 微信文件传输里面也有几篇12.6号的<Akuna Capital电面面经><2016最流行的Java EE服务器 ...
- BUPT复试专题—图像识别(2014-2)
题目描述 在图像识别中,我们经常需要分析特定图像中的一些特征,而其中很重要的一点就是识别出图像的多个区域.在这个问题中,我们将给定一幅N xM的图像,其中毎个1 x 1的点都用一个[0, 255]的值 ...
- 关于Java基础的一些笔试题总结
针对近期腾讯.京东.网易等公司的笔试,遇到一些有关Java基础的问题,在此总结,希望能通过这几道经典问题题发散,举一反三,借此打牢基础!自己总结,望提出宝贵意见! 一.关于null的一道小题 先开开 ...
- start_kernel——mm_init_owner
全部任务都具有自己的内存,启动阶段中的当前任务必须具备属于自己的内存. mm_init_owner()函数传递init_mm和init_task參数 mm/init-mm.c struct mm_st ...
- 仿MIUI音量变化环形进度条实现
Android中使用环形进度条的业务场景事实上蛮多的,比方下载文件的时候使用环形进度条.会给用户眼前一亮的感觉:再比方我大爱的MIUI系统,它的音量进度条就是使用环形进度条,尽显小米"为发烧 ...
- Python--学习过程
基础篇 Python基础篇 Python的数据类型 作业总结