传送门

解题思路

  以每个颜色为根开一棵权值线段树,下标就是$dfs$序,其余都是基本操作,要动态开点。

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm> using namespace std;
const int N=100005;
const int M=N*20; inline int rd(){
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)) f=ch=='-'?0:1,ch=getchar();
while(isdigit(ch)) x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
return f?x:-x;
} inline int max(int x,int y) {return x>y?x:y;} int n,q,head[N],cnt,to[N<<1],nxt[N<<1];
int C[N],W[N],siz[N],top[N];
int dep[N],id[N],fa[N],son[N],num,pool[N],cur; struct Segment_tree{
int rt[N],sum[M],ls[M],rs[M],tot,Max[M];
inline int new_node(){
return (cur?(pool[cur--]):(++tot));
}
void update(int &x,int l,int r,int pos,int k){
if(!x) x=new_node();
if(l==r) {
sum[x]=k; Max[x]=k;
if(!k) pool[++cur]=x,x=0;
return;
}
int mid=(l+r)>>1;
if(pos<=mid) update(ls[x],l,mid,pos,k);
else update(rs[x],mid+1,r,pos,k);
sum[x]=sum[ls[x]]+sum[rs[x]];
Max[x]=max(Max[ls[x]],Max[rs[x]]);
if(!sum[x]) {pool[++cur]=x;x=0;}
}
int query_sum(int x,int l,int r,int L,int R){
if(!x) return 0; if(L<=l && r<=R) return sum[x];
int mid=(l+r)>>1,ret=0;
if(L<=mid) ret+=query_sum(ls[x],l,mid,L,R);
if(mid<R) ret+=query_sum(rs[x],mid+1,r,L,R);
return ret;
}
int query_max(int x,int l,int r,int L,int R){
if(!x) return 0; if(L<=l && r<=R) return Max[x];
int mid=(l+r)>>1,ret=0;
if(L<=mid) ret=max(ret,query_max(ls[x],l,mid,L,R));
if(mid<R) ret=max(ret,query_max(rs[x],mid+1,r,L,R));
return ret;
}
inline void BUILD(){
for(int i=1;i<=n;i++) update(rt[C[i]],1,n,id[i],W[i]);
}
}tree; inline void add(int bg,int ed){
to[++cnt]=ed,nxt[cnt]=head[bg],head[bg]=cnt;
} void dfs1(int x,int f,int d){
fa[x]=f; siz[x]=1; dep[x]=d;
int maxson=-1,u;
for(int i=head[x];i;i=nxt[i]){
u=to[i]; if(u==f) continue;
dfs1(u,x,d+1); siz[x]+=siz[u];
if(siz[u]>maxson) maxson=siz[u],son[x]=u;
}
} void dfs2(int x,int topf){
id[x]=++num; top[x]=topf; if(!son[x]) return;
dfs2(son[x],topf); int u;
for(int i=head[x];i;i=nxt[i]){
u=to[i]; if(u==son[x] || u==fa[x]) continue;
dfs2(u,u);
}
} inline int Qsum(int x,int y){
int ret=0,CC=C[y];
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]) swap(x,y);
ret+=tree.query_sum(tree.rt[CC],1,n,id[top[x]],id[x]);
x=fa[top[x]];
}
if(dep[x]>dep[y]) swap(x,y);
ret+=tree.query_sum(tree.rt[CC],1,n,id[x],id[y]);
return ret;
} inline int Qmax(int x,int y){
int ret=0,CC=C[y];
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]) swap(x,y);
ret=max(ret,tree.query_max(tree.rt[CC],1,n,id[top[x]],id[x]));
x=fa[top[x]];
}
if(dep[x]>dep[y]) swap(x,y);
ret=max(ret,tree.query_max(tree.rt[CC],1,n,id[x],id[y]));
return ret;
} int main(){
n=rd(),q=rd(); int x,y; char s[5];
for(int i=1;i<=n;i++) W[i]=rd(),C[i]=rd();
for(int i=1;i<n;i++){
x=rd(),y=rd();
add(x,y); add(y,x);
}
dfs1(1,0,0); dfs2(1,1); tree.BUILD();
while(q--){
scanf("%s",s+1); x=rd(),y=rd();
if(s[2]=='C') {
tree.update(tree.rt[C[x]],1,n,id[x],0); C[x]=y;
tree.update(tree.rt[C[x]],1,n,id[x],W[x]);
}
else if(s[2]=='W') tree.update(tree.rt[C[x]],1,n,id[x],y),W[x]=y;
else if(s[2]=='S') printf("%d\n",Qsum(x,y));
else printf("%d\n",Qmax(x,y));
}
return 0;
}

BZOJ 3531: [Sdoi2014]旅行(树链剖分+线段树)的更多相关文章

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

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

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

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

  3. BZOJ.4034 [HAOI2015]树上操作 ( 点权树链剖分 线段树 )

    BZOJ.4034 [HAOI2015]树上操作 ( 点权树链剖分 线段树 ) 题意分析 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三种: 操作 1 :把某个节点 ...

  4. BZOJ.1036 [ZJOI2008]树的统计Count ( 点权树链剖分 线段树维护和与最值)

    BZOJ.1036 [ZJOI2008]树的统计Count (树链剖分 线段树维护和与最值) 题意分析 (题目图片来自于 这里) 第一道树链剖分的题目,谈一下自己的理解. 树链剖分能解决的问题是,题目 ...

  5. BZOJ 3672[NOI2014]购票(树链剖分+线段树维护凸包+斜率优化) + BZOJ 2402 陶陶的难题II (树链剖分+线段树维护凸包+分数规划+斜率优化)

    前言 刚开始看着两道题感觉头皮发麻,后来看看题解,发现挺好理解,只是代码有点长. BZOJ 3672[NOI2014]购票 中文题面,题意略: BZOJ 3672[NOI2014]购票 设f(i)f( ...

  6. bzoj 4196 [Noi2015]软件包管理器 (树链剖分+线段树)

    4196: [Noi2015]软件包管理器 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 2852  Solved: 1668[Submit][Sta ...

  7. bzoj 2157: 旅游【树链剖分+线段树】

    裸的树链剖分+线段树 但是要注意一个地方--我WA了好几次才发现取完相反数之后max值和min值是要交换的-- #include<iostream> #include<cstdio& ...

  8. BZOJ 3589 动态树 (树链剖分+线段树)

    前言 众所周知,90%90\%90%的题目与解法毫无关系. 题意 有一棵有根树,两种操作.一种是子树内每一个点的权值加上一个同一个数,另一种是查询多条路径的并的点权之和. 分析 很容易看出是树链剖分+ ...

  9. 【BZOJ-2325】道馆之战 树链剖分 + 线段树

    2325: [ZJOI2011]道馆之战 Time Limit: 40 Sec  Memory Limit: 256 MBSubmit: 1153  Solved: 421[Submit][Statu ...

  10. 【BZOJ2243】[SDOI2011]染色 树链剖分+线段树

    [BZOJ2243][SDOI2011]染色 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的 ...

随机推荐

  1. VC++ 创建及调用Dll

    一._stdcall 被这个关键字修饰的函数,其参数都是从右向左通过堆栈传递的(__fastcall 的前面部分由ecx,edx传), 函数调用在返回前要由被调用者清理堆栈. 这个关键字主要见于Mic ...

  2. Linux 下查看用户组信息

    1.id 通过id 可以直接查看到当前登陆用户的uid, group id , group name 等等.. 2.groups

  3. codeforces 557E Ann and Half-Palindrome

    题意简述 给定一个字符串(长度不超过5000 且只包含a.b)求满足如下所示的半回文子串中字典序第k大的子串 ti = t|t| - i + 1(|t|为字符串长度)   -------------- ...

  4. springBoot JPA PageAble分页查询出错,PropertyReferenceException: No property creation found for type

    PropertyReferenceException: No property creation found for type @RequestParam(required = false, defa ...

  5. rm -rf无法删除文件解决方法

    # 列出 file.sh 文件的属性 lsattr file.sh # 列出当前目录下所有文件以及文件夹的属性 lsattr # 为 file.sh 文件增加 i 标识 chattr +i file. ...

  6. xcode-select: error: tool 'xcodebuild' requires Xcode, but active developer directory '/Library/Developer/CommandLineTools' is a command line tools instance

    运行xcode命令报错: sh-3.2# xcodebuild xcode-select: error: tool 'xcodebuild' requires Xcode, but active de ...

  7. ExecutorException: A query was run and no Result Maps were found for the Mapped Statement ‘com.win.mall.dao.CartMapper.test’. It’s likely that neither a Result Type nor a Result Map was specified.

    ExecutorException: A query was run and no Result Maps were found for the Mapped Statement 'com.win.m ...

  8. Tomcat安装后修改路径方法

    tomcat+mysql+jdk 本地已经安装tomcat.mysql.jdk服务,需要更改安装目录由D盘改为C盘,方法如下 一.停止tomcat.mysql服务 二.安装文件由D盘拷贝到C盘,原D盘 ...

  9. css深入理解overflow

    1.基本属性 visible(默认值) 超出部分仍然正常显示 hidden 超出后隐藏 scroll 滚动条一致显示 auto 自适应 显示或隐藏滚动条 inherit overflow  =  ov ...

  10. MongoDB Windows之MSI安装

    MSI安装 下载地址:https://www.mongodb.com/download-center/community Version根据自己所需要的版本下载,OS根据自己电脑选择(我是Window ...