[题解]luogu_P3313_旅行(树剖
时间:2019-10-22
本文章向大家介绍[题解]luogu_P3313_旅行(树剖,主要包括[题解]luogu_P3313_旅行(树剖使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
树剖,其实信仰就是颜色,对于这种颜色问题我们可以考虑维护每种颜色的位置,对每种颜色用数据结构维护,可以支持合并之类的一些操作,这里可以对每个颜色维护一个动态开点权值线段树,线段树维护此颜色某点的权值,没有就是不在这个颜色里,修改直接删除再修改之类的即可
#include<bits/stdc++.h> #define mid ((l+r)>>1) using namespace std; const int maxn=100009; int n,m,w[maxn],c[maxn],tot; struct node{ int v,nxt; }e[maxn<<1]; int head[maxn],cnt; inline void add(int u,int v){ e[++cnt].v=v;e[cnt].nxt=head[u];head[u]=cnt; } int fa[maxn],dep[maxn],siz[maxn],son[maxn],dfn[maxn],id[maxn],top[maxn]; void dfs1(int x,int f){ siz[x]=1;dep[x]=dep[f]+1;fa[x]=f; for(int i=head[x];i;i=e[i].nxt){ int y=e[i].v;if(y==f)continue; dfs1(y,x); siz[x]+=siz[y]; if(siz[y]>siz[son[x]])son[x]=y; } } void dfs2(int x,int tp){ top[x]=tp; dfn[x]=++tot; id[tot]=x; if(!son[x])return; dfs2(son[x],tp); for(int i=head[x];i;i=e[i].nxt){ int y=e[i].v;if(y==fa[x]||y==son[x])continue; dfs2(y,y); } } int root[maxn],ls[maxn*30],rs[maxn*30]; struct ttt{ int mx,sum; }t[maxn*30]; inline void upd(int x){ t[x].sum=t[ls[x]].sum+t[rs[x]].sum; t[x].mx=max(t[ls[x]].mx,t[rs[x]].mx); } inline void change(int &x,int l,int r,int pos,int val){//dfs序为pos,评级val if(!x)x=++tot; t[x].mx=max(t[x].mx,val),t[x].sum+=val; if(l==r)return; if(pos<=mid)change(ls[x],l,mid,pos,val); else change(rs[x],mid+1,r,pos,val); } inline void del(int &x,int l,int r,int pos){ if(l==r){ t[x].sum=t[x].mx=0;return; } if(pos<=mid)del(ls[x],l,mid,pos); else del(rs[x],mid+1,r,pos); upd(x); } inline int qSum(int x,int l,int r,int L,int R){ if(L<=l&&r<=R)return t[x].sum; int ans=0; if(L<=mid)ans+=qSum(ls[x],l,mid,L,R); if(R>mid)ans+=qSum(rs[x],mid+1,r,L,R); return ans; } inline int qMx(int x,int l,int r,int L,int R){ if(L<=l&&r<=R)return t[x].mx; int ans=0; if(L<=mid)ans=max(ans,qMx(ls[x],l,mid,L,R)); if(R>mid)ans=max(ans,qMx(rs[x],mid+1,r,L,R)); return ans; } inline int qMxRoute(int x,int y,int val){ int ans=0; while(top[x]!=top[y]){ if(dep[top[x]]<dep[top[y]])swap(x,y); ans=max(ans,qMx(root[val],1,n,dfn[top[x]],dfn[x])); x=fa[top[x]]; } if(dep[x]<dep[y])swap(x,y); ans=max(ans,qMx(root[val],1,n,dfn[y],dfn[x])); return ans; } inline int qSumRoute(int x,int y,int val){ int ans=0; while(top[x]!=top[y]){ if(dep[top[x]]<dep[top[y]])swap(x,y); ans+=qSum(root[val],1,n,dfn[top[x]],dfn[x]); x=fa[top[x]]; } if(dep[x]<dep[y])swap(x,y); ans+=qSum(root[val],1,n,dfn[y],dfn[x]); return ans; } int main(){ // freopen("test.out","w",stdout); scanf("%d%d",&n,&m); for(int i=1;i<=n;i++)scanf("%d%d",&w[i],&c[i]); for(int i=1,u,v;i<n;i++){ scanf("%d%d",&u,&v);add(u,v);add(v,u); } dfs1(1,0);dfs2(1,1); for(int i=1;i<=n;i++)change(root[c[i]],1,n,dfn[i],w[i]); char op[10]; for(int i=1,x,y;i<=m;i++){ scanf("%s",op); scanf("%d%d",&x,&y); if(op[1]=='C'){ del(root[c[x]],1,n,dfn[x]); change(root[y],1,n,dfn[x],w[x]); c[x]=y; } else if(op[1]=='W'){ del(root[c[x]],1,n,dfn[x]); change(root[c[x]],1,n,dfn[x],y); w[x]=y; } else if(op[1]=='S')printf("%d\n",qSumRoute(x,y,c[x])); else printf("%d\n",qMxRoute(x,y,c[x])); } }
原文地址:https://www.cnblogs.com/superminivan/p/11718907.html
- NYOJ------汉诺塔(一)
- HDUOJ----Coin Change
- Golang语言社区--列出目录和遍历目录的方法
- HDUOJ-------单词数
- insert导致的性能问题大排查(r11笔记第26天)
- NYOJ-----最少乘法次数
- nyOJ-----韩信点兵
- HDUOJ-----A == B ?
- 用Oracle的眼光来学习MySQL 5.7的sys(上)(r11笔记第24天)
- Golang下通过syscall调用win32的api
- NYOJ----蛇形填数
- Golang语言 syscall 例子
- 用Oracle的眼光来学习MySQL 5.7的sys(下)(r11笔记第25天)
- HDUOJ-----Climbing Worm
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Linux中让alias设置永久生效的方法详解
- Centos系统下“无法打开并写入文件”问题的解决
- 如何在Linux下设置录音笔时间
- Linux下ZooKeeper分布式集群安装教程
- CentOS 6.5中利用yum搭建LNMP环境的步骤详解
- Linux下Kafka分布式集群安装教程
- Centos下升级Python及Mongodb驱动安装问题
- centOS6中使用crontab定时运行执行jar程序的脚本
- 基于cobbler 实现自动安装linux系统
- Polysh命令实现多日志查询的方法示例
- linux中启动tomcat后浏览器无法访问的解决方法
- Linux查看系统配置常用命令详解
- LNMP下提示File not found问题的解决方法
- Linux 配置SSH免密登录 “ssh-keygen”的基本用法
- 详解Ubuntu 16.04 pycharm设置桌面快捷启动方式