[ZJOI2008]树的统计
来源:互联网 发布:单片机组成 编辑:程序博客网 时间:2024/06/15 22:46
[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本身
输入输出格式
输入格式:
输入文件的第一行为一个整数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”的操作,每行输出一个整数表示要求输出的结果。
输入样例#1:
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
输出样例#1:
4
1
2
2
10
6
5
6
5
16
说明:
对于100%的数据,保证1<=n<=30000,0<=q<=200000;中途操作中保证每个节点的权值w在-30000到30000之间。
题解:
树链剖分,维护max和sum就可以了。
代码:
#include<cstdio>#include<iostream>#include<cstring>#include<cstdlib>using namespace std;const int max_n = 300001;const int inf = 1e9+7;struct tree_l{int l,r;int max,num,tot;}tree[max_n*4];char c[11];int point[max_n],nxt[max_n],v[max_n],val[max_n];int fa[max_n],top[max_n],size[max_n],rank_n[max_n],deep[max_n];int n,m,a,b,q,tot,tans,mans,root;inline void init(){memset(point,-1,sizeof(point));memset(nxt,-1,sizeof(nxt));tot=-1; root=1;}inline void update(int now){tree[now].tot=tree[now<<1].tot+tree[(now<<1)+1].tot;tree[now].max=max(tree[now<<1].max,tree[(now<<1)+1].max);}inline void addedge(int x,int y){++tot; nxt[tot]=point[x]; point[x]=tot; v[tot]=y;++tot; nxt[tot]=point[y]; point[y]=tot; v[tot]=x; }inline void change(int now,int l,int r,int val){int lr=tree[now].l,rr=tree[now].r;if(l<=lr && rr<=r){tree[now].tot=val;tree[now].num=val;tree[now].max=val;return;}int mid=(lr+rr)>>1;if(l<=mid) change(now<<1,l,r,val);if(r>mid) change((now<<1)+1,l,r,val);update(now);}inline void build(int now,int l,int r){tree[now].l=l; tree[now].r=r;if(l==r){tree[now].max=tree[now].num=tree[now].tot=-inf;return;}int mid=(l+r)>>1; build(now<<1,l,mid); build((now<<1)+1,mid+1,r);}inline void dfs1(int now,int f){fa[now]=f;deep[now]=deep[f]+1;size[now]=1;for(int i=point[now]; i!=-1; i=nxt[i]) if(v[i]!=f) { dfs1(v[i],now); size[now]+=size[v[i]]; }}inline void dfs2(int now,int tip){top[now]=tip;rank_n[now]=++tot;change(1,tot,tot,val[now]);int mson=0;if(now!=root && nxt[point[now]]==-1) return;for(int i=point[now]; i!=-1; i=nxt[i]) if(size[v[i]]<size[now] && size[v[i]]>size[mson]) mson=v[i];dfs2(mson,tip);for(int i=point[now]; i!=-1; i=nxt[i]) if(size[v[i]]<size[now] && v[i]!=mson)dfs2(v[i],v[i]);}inline void query(int now,int l,int r){int lr=tree[now].l,rr=tree[now].r;if(l<=lr && rr<=r){mans=max(tree[now].max,mans);tans+=tree[now].tot;return;}int mid=(lr+rr)>>1;if(l<=mid) query(now<<1,l,r);if(r>mid) query((now<<1)+1,l,r);}inline void squery(int x,int y){while(top[x]!=top[y]){if(deep[top[x]]<deep[top[y]]) swap(x,y);query(1,rank_n[top[x]],rank_n[x]);x=fa[top[x]]; }if(rank_n[x]>rank_n[y]) swap(x,y);query(1,rank_n[x],rank_n[y]);}int main(){//freopen("bzoj_1036.in","r",stdin);//freopen("bzoj_1036.out","w",stdout);scanf("%d",&n);init();for(int i=1; i<=n-1; ++i){scanf("%d%d",&a,&b);addedge(a,b);}for(int i=1; i<=n; ++i) scanf("%d",&val[i]); tot=0;build(1,1,n);dfs1(root,1);dfs2(root,root);scanf("%d",&q);for(int i=1; i<=q; ++i){scanf("%s%d%d",c,&a,&b);tans=0; mans=-inf;if(c[3]=='N') change(1,rank_n[a],rank_n[a],b);if(c[3]=='X') squery(a,b),printf("%d\n",mans);if(c[3]=='M') squery(a,b),printf("%d\n",tans);}return 0;}
阅读全文
0 0
- 【ZJOI2008】树的统计
- 【ZJOI2008】树的统计
- 【ZJOI2008】树的统计
- 【ZJOI2008】树的统计
- 树的统计 ZJOI2008
- [ZJOI2008]树的统计
- [ZJOI2008]树的统计Count
- [ZJOI2008]树的统计Count
- ZJOI2008树的统计bzoj1036
- BZOJ1036 ZJOI2008 树的统计
- [ZJOI2008]树的统计Count
- 【BZOJ1036】【ZJOI2008】树的统计
- ZJOI2008 树的统计 树链剖分
- [ZJOI2008]树的统计Count
- [ZJOI2008]树的统计Count
- JZOJsenior2256.【ZJOI2008】树的统计
- 【ZJOI2008】【link-cut tree】树的统计
- 1036: [ZJOI2008]树的统计Count 树链剖分裸题
- git常见用法
- 在Visual Studio Code中配置GO开发环境
- STM32从入门到精通
- 简单易懂的Flex布局教程,附送flex-demo源码
- 编写一个程序,实现字符串大小写的转换并倒序输出
- [ZJOI2008]树的统计
- Oracle 删除重复数据只留一条
- Hive 之 数据倾斜优化
- Markdown 常用语法
- POJ3436(最大流)
- 语音转文字转换器、绿色免安装版【推荐!推荐!推荐!】
- VB.net 数据库学习access
- PHP中的面向对象和面向过程
- Spring mvc interceptor配置拦截器,没有登录跳到登录页