[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 ...
随机推荐
- 三、jQuery--jQuery基础--jQuery基础课程--第10章 jQuery UI型插件
1.拖曳插件——draggable 拖曳插件draggable的功能是拖动被绑定的元素,当这个jQuery UI插件与元素绑定后,可以通过调用draggable()方法,实现各种拖曳元素的效果,调用格 ...
- NSDatePicker && NSDate
UIDatePicker *datePicker = [[UIDatePicker alloc]init]; datePicker.datePickerMode = UIDatePickerModeD ...
- 利用bak文件恢复数据库问题小结
对备份的基础理解: --完整备份:完整备份会备份所有数据的区和少量的日志(日志文件用于恢复数据保持数据一致性).由于差异备份需要依据最后一次完整备份,因此完整备份会清楚一些分配位图数据. --差异备份 ...
- C/C++学习笔记----指针的理解
指针是C/C++编程中的重要概念之一,也是最容易产生困惑并导致程序出错的问题之一.利用指针编程可以表示各种数据结构,通过指针可使用主调函数和被调函数之间共享变量或数据结构,便于实现双向数据通讯:指针能 ...
- 与你相遇好幸运,Waterline的属性
>支持的数据类型: string / text / integer / float / date / time / datetime / boolean / binary / array / j ...
- ASP.NET Web Api 使用CacheCow和ETag缓存资源(转载)
转载地址:http://www.cnblogs.com/fzrain/p/3618887.html 前言 本文将使用一个开源框架CacheCow来实现针对Http请求资源缓存,本文主要介绍服务器端的缓 ...
- Mysql中文乱码问题完美解决方案
drop database`netctoss_demo` ;CREATE DATABASE `netctoss_demo` CHARACTER SET 'utf8' COLLATE 'utf8_gen ...
- redmine安装部署
http://www.sxt.cn/u/4647/blog/5557 http://blog.chinaunix.net/uid-26729093-id-4669508.html http://my. ...
- 深入剖析iLBC的丢包补偿技术(PLC)
转自:http://blog.csdn.net/wanggp_2007/article/details/5136609 丢包补偿技术(Packet Loss Concealment——PLC)是iLB ...
- Arduino101学习笔记(六)—— 高级IO
1.位移输出函数(8位) 输入value数据后Arduino会自动把数据移动分配到8个并行输出端. 其中dataPin为连接DS的引脚号, clockPin为连接SH_CP的引脚号, bitOrder ...