P3313 [SDOI2014]旅行
树链剖分+动态线段树(并不是lct)
显然的,我们对于每一个宗教都要维护一个线段树。
(那么空间不是爆炸了吗)
在这里引入:动态开点线段树
就是需要的点开起来,不需要的就不开。
其他地方和正常的线段树差不多
这样可以省下一堆空间。
code:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cctype>
#include<queue>
#define re register
using namespace std;
template <typename T> inline T min(T &a,T &b) {return a<b ?a:b;}
template <typename T> inline T max(T &a,T &b) {return a>b ?a:b;}
template <typename T> inline void read(T &x){
char c=getchar(); x=; bool f=;
while(!isdigit(c)) f= !f||c=='-' ? :,c=getchar();
while(isdigit(c)) x=(x<<)+(x<<)+(c^),c=getchar();
x= f ? x:-x;
}
template <typename T> inline void output(T x){
if(!x) {putchar(); return ;}
if(x<) putchar('-'),x=-x;
int wt[],l=;
while(x) wt[++l]=x%,x/=;
while(l) putchar(wt[l--]+);
}
typedef int arr[];
struct data{ //结构体存点
int l,r,mxd,sum;
void clear() {l=r=mxd=sum=;}
}a[]; //尽量开大
queue <int> lit;
int n,m,cnt,tot,u;
arr d,fa,siz,bgs,tp,val,sp,id,hd,ed,rt;
int nxt[],poi[];
inline void add_(int x,int y){
nxt[ed[x]]=++cnt; hd[x]= hd[x] ? hd[x]:cnt;
ed[x]=cnt; poi[cnt]=y;
}
inline void modify(int &o,int l,int r,int x,int v){ //引用地址便于修改
if(!o){
if(!lit.empty()) o=lit.front(),lit.pop(); //内存池节省空间
else o=++u;
}
if(l==r) {a[o].sum=a[o].mxd=v; return;}
int mid=l+((r-l)>>);
if(x<=mid) modify(a[o].l,l,mid,x,v);
else modify(a[o].r,mid+,r,x,v);
a[o].sum=a[a[o].l].sum+a[a[o].r].sum;
a[o].mxd=max(a[a[o].l].mxd,a[a[o].r].mxd);
}
inline void remov(int &o,int l,int r,int x){
if(l==r) {a[o].clear(); lit.push(o),o=; return;}
int mid=l+((r-l)>>);
if(x<=mid) remov(a[o].l,l,mid,x);
else remov(a[o].r,mid+,r,x);
a[o].sum=a[a[o].l].sum+a[a[o].r].sum;
a[o].mxd=max(a[a[o].l].mxd,a[a[o].r].mxd);
if(!a[o].l&&!a[o].r) a[o].clear(),lit.push(o),o=; //左右子树都空->该点为空->删掉
}
inline int query1(int o,int l,int r,int x1,int x2){
if(!o) return ; //注意空树要跳出
if(x1<=l&&r<=x2) return a[o].sum;
int mid=l+((r-l)>>),res=;
if(x1<=mid) res+=query1(a[o].l,l,mid,x1,x2);
if(x2>mid) res+=query1(a[o].r,mid+,r,x1,x2);
return res;
}
inline int query2(int o,int l,int r,int x1,int x2){
if(!o) return ;
if(x1<=l&&r<=x2) return a[o].mxd;
int mid=l+((r-l)>>),res=;
if(x1<=mid) res=max(res,query2(a[o].l,l,mid,x1,x2));
if(x2>mid) res=max(res,query2(a[o].r,mid+,r,x1,x2));
return res;
}
inline void dfs1(int x,int _fa){
d[x]=d[_fa]+,fa[x]=_fa,siz[x]=;
for(int i=hd[x];i;i=nxt[i])
if(poi[i]!=_fa){
dfs1(poi[i],x);
siz[x]+=siz[poi[i]];
if(siz[bgs[x]]<siz[poi[i]]) bgs[x]=poi[i];
}
}
inline void dfs2(int x,int _top){
id[x]=++tot,tp[x]=_top;
if(siz[x]==) return;
dfs2(bgs[x],_top);
for(int i=hd[x];i;i=nxt[i])
if(poi[i]!=fa[x]&&poi[i]!=bgs[x])
dfs2(poi[i],poi[i]);
}
inline int ask1(int x,int y){
int col=val[x],res=;
while(tp[x]!=tp[y]){
if(d[tp[x]]<d[tp[y]]) swap(x,y);
res+=query1(rt[col],,n,id[tp[x]],id[x]);
x=fa[tp[x]];
}if(d[x]>d[y]) swap(x,y);
return res+query1(rt[col],,n,id[x],id[y]);
}
inline int ask2(int x,int y){
int col=val[x],res=;
while(tp[x]!=tp[y]){
if(d[tp[x]]<d[tp[y]]) swap(x,y);
res=max(res,query2(rt[col],,n,id[tp[x]],id[x]));
x=fa[tp[x]];
}if(d[x]>d[y]) swap(x,y);
return max(res,query2(rt[col],,n,id[x],id[y]));
}
//------树剖基础操作--------
inline void change1(int x,int v){
remov(rt[val[x]],,n,id[x]);
modify(rt[val[x]=v],,n,id[x],sp[x]);
}//宗教改变:从原来那棵树删掉该点,再加到新树上
inline void change2(int x,int v){
modify(rt[val[x]],,n,id[x],sp[x]=v);
}//评价改变:直接修改
int main(){
read(n),read(m); int q1,q2; char opt[];
for(re int i=;i<=n;++i) read(sp[i]),read(val[i]);
for(re int i=;i<n;++i) read(q1),read(q2),add_(q1,q2),add_(q2,q1);
dfs1(,); dfs2(,);
for(re int i=;i<=n;++i) modify(rt[val[i]],,n,id[i],sp[i]);
for(re int i=;i<=m;++i){
scanf("%s",opt); read(q1),read(q2);
if(opt[]=='C'){
if(opt[]=='C') change1(q1,q2);
else change2(q1,q2);
}else{
if(opt[]=='S') output(ask1(q1,q2));
else output(ask2(q1,q2));
putchar('\n');
}
}return ;
}
P3313 [SDOI2014]旅行的更多相关文章
- [luogu P3313] [SDOI2014]旅行
[luogu P3313] [SDOI2014]旅行 题目描述 S国有N个城市,编号从1到N.城市间用N-1条双向道路连接,满足从一个城市出发可以到达其它所有城市.每个城市信仰不同的宗教,如飞天面条神 ...
- 洛谷 P3313 [SDOI2014]旅行 解题报告
P3313 [SDOI2014]旅行 题目描述 S国有N个城市,编号从1到N.城市间用N-1条双向道路连接,满足从一个城市出发可以到达其它所有城市.每个城市信仰不同的宗教,如飞天面条神教.隐形独角兽教 ...
- P3313 [SDOI2014]旅行——树链剖分+线段树(动态开点?)
P3313 [SDOI2014]旅行 一棵树,其中的点分类,点有权值,在一条链上找到一类点中的最大值或总和: 树链剖分把树变成链: 把每个宗教单开一个线段树,维护区间总和和最大值: 宗教很多,需要动态 ...
- 洛谷 P3313 [SDOI2014]旅行
题目描述 S国有N个城市,编号从1到N.城市间用N-1条双向道路连接,满足从一个城市出发可以到达其它所有城市.每个城市信仰不同的宗教,如飞天面条神教.隐形独角兽教.绝地教都是常见的信仰. 为了方便,我 ...
- 洛谷P3313 [SDOI2014]旅行 题解 树链剖分+线段树动态开点
题目链接:https://www.luogu.org/problem/P3313 这道题目就是树链剖分+线段树动态开点. 然后做这道题目之前我们先来看一道不考虑树链剖分之后完全相同的线段树动态开点的题 ...
- 洛谷P3313 [SDOI2014]旅行(树链剖分 动态开节点线段树)
题意 题目链接 Sol 树链剖分板子 + 动态开节点线段树板子 #include<bits/stdc++.h> #define Pair pair<int, int> #def ...
- [SDOI2014]旅行
洛谷 P3313 [SDOI2014]旅行 https://www.luogu.org/problem/show?pid=3313 题目描述 S国有N个城市,编号从1到N.城市间用N-1条双向道路连接 ...
- BZOJ 3531: [Sdoi2014]旅行 [树链剖分]
3531: [Sdoi2014]旅行 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 1685 Solved: 751[Submit][Status] ...
- 【BZOJ3531】[Sdoi2014]旅行 树链剖分+动态开点线段树
[BZOJ3531][Sdoi2014]旅行 Description S国有N个城市,编号从1到N.城市间用N-1条双向道路连接,满足从一个城市出发可以到达其它所有城市.每个城市信仰不同的宗教,如飞天 ...
随机推荐
- windows10下笔记本电脑外接显示器设置
笔记本屏幕小,故外接一个显示器,方便使用. 我的电脑没有VGA接口,有HDMI接口,所以我买了一个HDMI到VGA接口转换器. 直接把外界显示器安装到笔记电脑上,如下图所示 接下来是屏幕设置 打开系统 ...
- python字典获取最大值的键的值
有时我们需要字典中数值最大的那个键的名字,使用max(dict, key=dict.get)函数非常的方便 key_name = max(my_dict, key=my_dict.get) 获取之后你 ...
- Cocos2d比较好的博客
1 .http://blog.csdn.net/bill_man/article/details/7202458 学习笔记 2.http://cocos2d-x.org/ 官网 3.http://ww ...
- POJ3468 a simple problem with integers 分块
题解:分块 解题报告: 是个板子题呢qwq 没什么可说的,加深了对分块的理解趴还是 毕竟这么简单的板子题我居然死去活来WA了半天才调出来,,,哭了QAQ 还是说下我错在了哪几个地方(...是的,有好几 ...
- Linux新建用户 useradd&groupadd
建立一个新组,并设置组ID加入系统:#groupadd -g 1000 sparkgroup #useradd -u 2000 -g sparkgroup sparkuser #mkdir -p /a ...
- javaScript错误(一)Cannot call method 'addEventListener' of null
Cannot call method 'addEventListener' of null 原因很简单,JavaScript代码中要引用到DOM对象,但是这个DOM对象在JavaScript执行后才会 ...
- python操作docx学习资料
1.博客 (1)写入参考 https://www.cnblogs.com/rencm/p/6285304.html (2)读取参考 http://www.cnblogs.com/zhanghongfe ...
- 第十八篇:融汇贯通--谈USB Video Class驱动
USB Video Class驱动是WINDOWS系统包含的一个针对于USB VIDEO 类的驱动程序. 好多project师都做过USB VIDEO设备端的开发, 基本的工作内容为: 使用FIRMW ...
- office 2016 install(office2016组件自定义安装激活程序) v5.9.3中文绿色版
下载地址 http://www.ddooo.com/softdown/71741.htm#dltab office 2016 install是目前下载office2016和office2016组件最 ...
- 协作工具 discord 和 slack
discord: https://discordapp.com/ slack: www.slack.com