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]旅行的更多相关文章

  1. [luogu P3313] [SDOI2014]旅行

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

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

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

  3. P3313 [SDOI2014]旅行——树链剖分+线段树(动态开点?)

    P3313 [SDOI2014]旅行 一棵树,其中的点分类,点有权值,在一条链上找到一类点中的最大值或总和: 树链剖分把树变成链: 把每个宗教单开一个线段树,维护区间总和和最大值: 宗教很多,需要动态 ...

  4. 洛谷 P3313 [SDOI2014]旅行

    题目描述 S国有N个城市,编号从1到N.城市间用N-1条双向道路连接,满足从一个城市出发可以到达其它所有城市.每个城市信仰不同的宗教,如飞天面条神教.隐形独角兽教.绝地教都是常见的信仰. 为了方便,我 ...

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

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

  6. 洛谷P3313 [SDOI2014]旅行(树链剖分 动态开节点线段树)

    题意 题目链接 Sol 树链剖分板子 + 动态开节点线段树板子 #include<bits/stdc++.h> #define Pair pair<int, int> #def ...

  7. [SDOI2014]旅行

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

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

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

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

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

随机推荐

  1. Oracle创建测试表

    试中文排序的数据库版本: SQL> select * from v$version; BANNER ----------------------------------------------- ...

  2. Spring接受前台的数据超过256出现如下异常:

    转载自:http://blog.csdn.net/dracotianlong/article/details/47604723 Spring接受前台的数据超过256出现如下异常: org.spring ...

  3. PHP 正则表达式抓取网页内容。

    我想用php抓取爱奇艺生活类型视频网页里面的元素,应该如何去做呢? 首先我要非常熟悉正则表达式,关于正则表达式的学习,我会写一篇博客一直学习的. 直接举例子: 这是一个爱奇艺生活视频的界面的网址 $u ...

  4. os.path 模块

    os.path.abspath(path) #返回绝对路径 os.path.basename(path) #返回文件名 os.path.commonprefix(list) #返回list(多个路径) ...

  5. MySQL ·InnoDB 文件系统之文件物理结构

    从上层的角度来看,InnoDB层的文件,除了redo日志外,基本上具有相当统一的结构,都是固定block大小,普遍使用的btree结构来管理数据.只是针对不同的block的应用场景会分配不同的页类型. ...

  6. ArcGIS earth 1.0 beta体验报告——给我一个按钮我将转动整个地球

    随着Esri研发中心的ArcGIS earth 1.0 beta版本的全新发布,声势浩大,很多人为之好奇静待观摩其阵容.抽出五分钟体验,良心用户,必得出炉一份体验报告了. -------------- ...

  7. Why is long2ip conversion important?

    Frequently Asked Questions about Convert long to IP address https://long2ip.com/faq/ What is long2ip ...

  8. 币安Binance API

    本文介绍币安Binance API General API Information The base endpoint is: https://api.binance.com All endpoint ...

  9. sql server 备份恢复效率

    sql server 备份恢复效率 如何提高备份的速度呢? 其实这个问题和如何让系统跑的更快是一样的,要想系统跑的更快,无非就是:优化系统,或者就是更好更强大的服务器,特别是更多的cpu.更大的内存. ...

  10. mysql 内置功能 事务 介绍

    事务用于将某些操作的多个SQL作为原子性操作,一旦有某一个出现错误,即可回滚到原来的状态,从而保证数据库数据完整性 创建数据库db12 create database db12 charset=utf ...