[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 ...
随机推荐
- history 清空历史记录 或 history不记录历史命令
# vi ~/.bash_history 清空里面的记录,并退出当前shell # exit(一定要退出当前shell) # history 1 vi ~/.bash_history 2 histor ...
- C#关键字params
using System; using System.Threading; namespace Test { /// <summary> /// params用法: 1.用来修饰方法的参数 ...
- Sublime Text3使用记录
概述 Sublime是一款很好用的程序编辑网站,主要说的就是编写网页代码,同时Sublime支持接口开发,致使网络上有很多大牛写的编辑插件也很多,使用起来也自如方便了好多,最近一直在用Sublime ...
- .NET MVC4 数据验证Model(二)
一.概述 MVC分为ViewModel.Control.View,对数据的封装MVC做的很好,确实是不错的WEB框架,针对MVC的ViewModel封装的也是相当的不错,最近做一个MVC的项目,采 ...
- SQLAlchemy高级ORM之改查删除及GROUP,JOIN...
按书上案例来的. #coding=utf-8 from datetime import datetime from sqlalchemy import (MetaData, Table, Column ...
- static_cast、dynamic_cast、reinterpret_cast、const_cast以及C强制类型转换的区别
static_cast 1. 基础类型之间互转.如:float转成int.int转成unsigned int等 2. 指针与void*之间互转.如:float*转成void*.CBase*转成void ...
- Spring+Hibernate+Oracle中的Clob操作配置
bean对象配置: <!-- 此处用于指定当前JDBC的实现,详见下面注解① --> <bean id="nativeJdbcExtractor" class=& ...
- JavaScript高级程序设计 读书笔记
第一章 JavaScript 简介 第二章 Html中使用JavaScript 第三章 基本概念 第四章 变量,作用域,内存 第五章 引用类型 第六章 面向对象 第七章 函数表达式 第八章 BOM 第 ...
- 如何安装sublime text2以及它的插件?
下载Sublime Text2的安装包,安装,安装后打开的界面如图 下面我们来给他安装插件,首先安装packagecontrol,打开菜单栏中的View-->show console 在 ...
- 在VS 2015中边调试边分析性能
(此文章同时发表在本人微信公众号"dotNET每日精华文章",欢迎右边二维码来关注.) 对代码进行性能分析,之前往往是一种独立的Profiling过程,现在在VS 2015中可以结 ...