题目大意:

  给出一个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]旅行 题解的更多相关文章

  1. 洛谷P3313 [SDOI2014]旅行 题解 树链剖分+线段树动态开点

    题目链接:https://www.luogu.org/problem/P3313 这道题目就是树链剖分+线段树动态开点. 然后做这道题目之前我们先来看一道不考虑树链剖分之后完全相同的线段树动态开点的题 ...

  2. 【BZOJ3531】[Sdoi2014]旅行 树链剖分+动态开点线段树

    [BZOJ3531][Sdoi2014]旅行 Description S国有N个城市,编号从1到N.城市间用N-1条双向道路连接,满足从一个城市出发可以到达其它所有城市.每个城市信仰不同的宗教,如飞天 ...

  3. BZOJ 3531: [Sdoi2014]旅行 [树链剖分]

    3531: [Sdoi2014]旅行 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 1685  Solved: 751[Submit][Status] ...

  4. bzoj 3531 [Sdoi2014]旅行(树链剖分,线段树)

    3531: [Sdoi2014]旅行 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 876  Solved: 446[Submit][Status][ ...

  5. [SDOI2014]旅行

    洛谷 P3313 [SDOI2014]旅行 https://www.luogu.org/problem/show?pid=3313 题目描述 S国有N个城市,编号从1到N.城市间用N-1条双向道路连接 ...

  6. B20J_3231_[SDOI2014]旅行_树链剖分+线段树

    B20J_3231_[SDOI2014]旅行_树链剖分+线段树 题意: S国有N个城市,编号从1到N.城市间用N-1条双向道路连接,城市信仰不同的宗教,为了方便,我们用不同的正整数代表各种宗教. S国 ...

  7. [luogu P3313] [SDOI2014]旅行

    [luogu P3313] [SDOI2014]旅行 题目描述 S国有N个城市,编号从1到N.城市间用N-1条双向道路连接,满足从一个城市出发可以到达其它所有城市.每个城市信仰不同的宗教,如飞天面条神 ...

  8. 洛谷 P3313 [SDOI2014]旅行 解题报告

    P3313 [SDOI2014]旅行 题目描述 S国有N个城市,编号从1到N.城市间用N-1条双向道路连接,满足从一个城市出发可以到达其它所有城市.每个城市信仰不同的宗教,如飞天面条神教.隐形独角兽教 ...

  9. bzoj 3531 [Sdoi2014]旅行 (树剖+线段树 动态开点)

    3531: [Sdoi2014]旅行 Time Limit: 40 Sec  Memory Limit: 512 MBSubmit: 2984  Solved: 1312[Submit][Status ...

随机推荐

  1. IOS常用正则表达式

    IOS常用正则表达式 正则表达式用于字符串处理.表单验证等场合,实用高效.现将一些常用的表达式收集于此,以备不时之需. 匹配中文字符的正则表达式: [\u4e00-\u9fa5] 评注:匹配中文还真是 ...

  2. 数据结构和算法 c#– 1.单项链表

    1.顺序存储结构 Array 1.引用类型(托管堆) 2.初始化时会设置默认值   2.链式存储结构 2.1.单向链表 2.2.循环链表 2.3.双向链表

  3. jQuery - 9.Ajax

    9.1 Ajax 的 XMLHttpRequest 对象 9.2 JQuery中的Ajax 9.2.1 load()方法 9.2.2 $.get() 9.2.3 $.post() 9.2.4 $.ge ...

  4. 莫队算法 2038: [2009国家集训队]小Z的袜子(hose)

    链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2038 2038: [2009国家集训队]小Z的袜子(hose) Time Limit: 20 ...

  5. java 杂物间 (一) Mybatis

    这里放置的是一些杂物,生人勿入. Token的一般parse 过程. @Test public void shouldDemonstrateGenericTokenReplacement() { Ge ...

  6. jq获取鼠标位置

    jq获取鼠标位置 <!DOCTYPE html> <html lang="en"> <head> <meta charset=" ...

  7. TortoiseSVN常用操作说明

    TortoiseSVN是windows下其中一个非常优秀的SVN客户端工具.通过使用它,我们可以可视化的管理我们的版本库.不过由于它只是一个客户端,所以它不能对版本库进行权限管理. TortoiseS ...

  8. WPF中加载高分辨率图片性能优化

    在最近的项目中,遇到一个关于WPF中同时加载多张图片时,内存占用非常高的问题. 问题背景: 在一个ListView中同时加载多张图片,注意:我们需要加载的图片分辨率非常高. 代码: XAML: < ...

  9. [Oracle] 生产上表的列类型更新

    由于粗心,数据库脚本生成的时候错将一个类型NUMBER(5)的字段类型改为 VARCHAR2(5) 直接进行表修改会报错,因为数据已经存在,不能进行更新: ); 大体思路如下:       将要更改类 ...

  10. Codeforces Round #337 (Div. 2) D. Vika and Segments 线段树 矩阵面积并

    D. Vika and Segments     Vika has an infinite sheet of squared paper. Initially all squares are whit ...