[Sdoi2014]旅行 题解
题目大意:
给出一个n个点的树,和m次操作。每个点有颜色和权值。 每次操作分4种 1:修改一个点的颜色 2:修改一个点的权值 3:询问从x到y的路径上,和x相同颜色的点的权值和(保证x,y同颜色) 4:询问从x到y的路径上,和x相同颜色的点的权值最大值(保证x,y同颜色)
思路:
树链剖分,用线段树来维护和以及最大值。
代码:
#include<cstdio>
#include<iostream>
#define M 3000009
using namespace std; int cnt,dfn,num,n,m,w[M],c[M],to[M<<],next[M<<],head[M],deep[M],size[M],pa[M],id[M],top[M],root[M],sum[M<<],mx[M<<],lc[M<<],rc[M<<]; void ins(int x,int y)
{
to[++cnt]=y,next[cnt]=head[x],head[x]=cnt;
} void dfs1(int x)
{
size[x]=;
for (int i=head[x];i;i=next[i])
if (pa[x]!=to[i])
{
deep[to[i]]=deep[x]+,pa[to[i]]=x;
dfs1(to[i]),size[x]+=size[to[i]];
}
} void dfs2(int x,int chain)
{
int i,k=;
id[x]=++dfn,top[x]=chain;
for (i=head[x];i;i=next[i])
if (deep[to[i]]>deep[x] && size[to[i]]>size[k]) k=to[i];
if (!k) return; dfs2(k,chain);
for (i=head[x];i;i=next[i])
if (pa[x]!=to[i] && k!=to[i]) dfs2(to[i],to[i]);
} void up_date(int k)
{
sum[k]=sum[lc[k]]+sum[rc[k]];
mx[k]=max(mx[lc[k]],mx[rc[k]]);
} void change(int &cur,int l,int r,int x,int val)
{
if (!cur) cur=++num;
if (l==r) { sum[cur]=mx[cur]=val; return; }
int mid=l+r>>;
if (x<=mid) change(lc[cur],l,mid,x,val);
else change(rc[cur],mid+,r,x,val);
up_date(cur);
} int ask_sum(int cur,int L,int R,int l,int r)
{
if (!cur) return ;
if (L==l && R==r) return sum[cur];
int mid=L+R>>;
if (r<=mid) return ask_sum(lc[cur],L,mid,l,r);
if (l>mid) return ask_sum(rc[cur],mid+,R,l,r);
return ask_sum(lc[cur],L,mid,l,mid)+ask_sum(rc[cur],mid+,R,mid+,r);
} int ask_max(int cur,int L,int R,int l,int r)
{
if (!cur) return ;
if (L==l && R==r) return mx[cur];
int mid=L+R>>;
if (r<=mid) return ask_max(lc[cur],L,mid,l,r);
if (l>mid) return ask_max(rc[cur],mid+,R,l,r);
return max(ask_max(lc[cur],L,mid,l,mid),ask_max(rc[cur],mid+,R,mid+,r));
} int Ask_Sum(int x,int y,int z)
{
int ans=;
for (;top[x]!=top[y];x=pa[top[x]])
{
if (deep[top[x]]<deep[top[y]]) swap(x,y);
ans+=ask_sum(root[z],,n,id[top[x]],id[x]);
}
if (deep[x]>deep[y]) swap(x,y);
return ans+ask_sum(root[z],,n,id[x],id[y]);
} int Ask_Max(int x,int y,int z)
{
int ans=-;
for (;top[x]!=top[y];x=pa[top[x]])
{
if (deep[top[x]]<deep[top[y]]) swap(x,y);
ans=max(ans,ask_max(root[z],,n,id[top[x]],id[x]));
}
if (deep[x]>deep[y]) swap(x,y);
return max(ans,ask_max(root[z],,n,id[x],id[y]));
} int main()
{
scanf("%d%d",&n,&m);
int i,x,y;
for (i=;i<=n;i++) scanf("%d%d",&w[i],&c[i]);
for (i=;i<n;i++) scanf("%d%d",&x,&y),ins(x,y),ins(y,x);
dfs1(),dfs2(,);
for (i=;i<=n;i++) change(root[c[i]],,n,id[i],w[i]);
for (i=;i<=m;i++)
{
char ch[];
scanf("%s%d%d",ch,&x,&y);
if (ch[]=='C')
if (ch[]=='C') change(root[c[x]],,n,id[x],),change(root[y],,n,id[x],w[x]),c[x]=y;
else change(root[c[x]],,n,id[x],y),w[x]=y;
else if (ch[]=='S') printf("%d\n",Ask_Sum(x,y,c[x]));
else printf("%d\n",Ask_Max(x,y,c[x]));
}scanf("%d",&n);
return ;
}
[Sdoi2014]旅行 题解的更多相关文章
- 洛谷P3313 [SDOI2014]旅行 题解 树链剖分+线段树动态开点
题目链接:https://www.luogu.org/problem/P3313 这道题目就是树链剖分+线段树动态开点. 然后做这道题目之前我们先来看一道不考虑树链剖分之后完全相同的线段树动态开点的题 ...
- 【BZOJ3531】[Sdoi2014]旅行 树链剖分+动态开点线段树
[BZOJ3531][Sdoi2014]旅行 Description S国有N个城市,编号从1到N.城市间用N-1条双向道路连接,满足从一个城市出发可以到达其它所有城市.每个城市信仰不同的宗教,如飞天 ...
- BZOJ 3531: [Sdoi2014]旅行 [树链剖分]
3531: [Sdoi2014]旅行 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 1685 Solved: 751[Submit][Status] ...
- bzoj 3531 [Sdoi2014]旅行(树链剖分,线段树)
3531: [Sdoi2014]旅行 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 876 Solved: 446[Submit][Status][ ...
- [SDOI2014]旅行
洛谷 P3313 [SDOI2014]旅行 https://www.luogu.org/problem/show?pid=3313 题目描述 S国有N个城市,编号从1到N.城市间用N-1条双向道路连接 ...
- B20J_3231_[SDOI2014]旅行_树链剖分+线段树
B20J_3231_[SDOI2014]旅行_树链剖分+线段树 题意: S国有N个城市,编号从1到N.城市间用N-1条双向道路连接,城市信仰不同的宗教,为了方便,我们用不同的正整数代表各种宗教. S国 ...
- [luogu P3313] [SDOI2014]旅行
[luogu P3313] [SDOI2014]旅行 题目描述 S国有N个城市,编号从1到N.城市间用N-1条双向道路连接,满足从一个城市出发可以到达其它所有城市.每个城市信仰不同的宗教,如飞天面条神 ...
- 洛谷 P3313 [SDOI2014]旅行 解题报告
P3313 [SDOI2014]旅行 题目描述 S国有N个城市,编号从1到N.城市间用N-1条双向道路连接,满足从一个城市出发可以到达其它所有城市.每个城市信仰不同的宗教,如飞天面条神教.隐形独角兽教 ...
- bzoj 3531 [Sdoi2014]旅行 (树剖+线段树 动态开点)
3531: [Sdoi2014]旅行 Time Limit: 40 Sec Memory Limit: 512 MBSubmit: 2984 Solved: 1312[Submit][Status ...
随机推荐
- Loadrunner11.0 录制手机App脚本的方法
使用Loadrunner录制手机终端App脚本 1. 说明 目前手机APP上的功能日益丰富,对手机应用功能的性能测试需求也越来越多.公司比较抠门没有花钱买Loadrunner,可怜我们工作中一直用的破 ...
- ActiveMQ的几种集群配置
ActiveMQ是一款功能强大的消息服务器,它支持许多种开发语言,例如Java, C, C++, C#等等.企业级消息服务器无论对服务器稳定性还是速度,要求都很高,而ActiveMQ的分布式集群则能很 ...
- 攻城狮在路上(壹) Hibernate(十四)--- Hibernate的检索方式(下)
本节介绍HQL和QBC的高级用法:各种连接查询.投影查询.报表查询.动态查询.集合过滤和子查询等.另外将归纳优化查询程序代码,从而提高查询性能的各种技巧.一.连接查询: HQL与QBC支持的各种连接类 ...
- Oracle 备份与恢复介绍
一.Oracle备份方式分类:Oracle有两类备份方式:(1)物理备份:是将实际组成数据库的操作系统文件从一处拷贝到另一处的备份过程,通常是从磁盘到磁带.物理备份又分为冷备份.热备份: (2)逻 ...
- PHP日期操作类代码-农历-阳历转换、闰年、计算天数等
<?php class Lunar { var $MIN_YEAR = 1891; var $MAX_YEAR = 2100; var $lunarInfo = array( array(0,2 ...
- @property中strong跟weak的区别
strong关键字与retain关似,用了它,引用计数自动+1,用实例更能说明一切 @property (nonatomic, strong) NSString *string1; @property ...
- 数据库是.frm,.myd,myi备份如何导入mysql (转)
今天找了个案例,琢磨了半天,才分析大概出来,数据库是.frm,.myd,myi备份,不会导入mysql,到网上找了些资料,导入成功. 首先说一下这几种文件是干什么的,*.frm是描述了表的结构,*.M ...
- POJ 1741 Tree 树分治
Tree Description Give a tree with n vertices,each edge has a length(positive integer less than 1 ...
- 浅谈JSON.parse()、JSON.stringify()和eval()的作用
(1)JSON.parse 函数 var json = '{"name":"GDT","age":23,"University&q ...
- 【T_SQL】 基础 事务
1.使用 T-SQL 语句来管理事务 开始事务:BEGIN TRANSACTION 提交事务:COMMIT TRANSACTION 回滚(撤销)事务:ROLLBAC ...