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. Saltstack之SSH

    salt-minion也可以不安装通过在master安装salt-ssh 1,安装 yum -y install salt-ssh 2,配置salt的花名册 vim /etc/salt/roster ...

  2. HDU 2037 - 今年暑假不AC - [经典 选择不相交区间 问题]

    是一道很经典的选择不相交区间的问题. 关于选择不相交区间,可以参考刘汝佳.也可以参考:http://blog.csdn.net/dgq8211/article/details/7534488 以及模板 ...

  3. ionic 下拉选择框中默认显示传入的参数

    开发过程当中遇到一个有趣的问题,如果我在第一个页面需要把 item { "ownerId" : 1 } 传递给第二个页面,并挂在$scope下 $scope.item = $sta ...

  4. Python爬虫框架Scrapy实例(四)下载中间件设置

    还是豆瓣top250爬虫的例子,添加下载中间件,主要是设置动态Uesr-Agent和代理IP Scrapy代理IP.Uesr-Agent的切换都是通过DOWNLOADER_MIDDLEWARES进行控 ...

  5. In MySQL, a zero number equals any string

    最近在做项目的过程中发现了一个问题 数据库表 test  有个字段是 target_id  int(11),这个字段可能为零 使用如下查询 select * from test where targe ...

  6. 《Nginx - 变量》- log_format/核心变量

    一:log_format - 概述 - log_format 用于管理 Nginx 的详细信息,日志管理等信息,很多都是基于这个来实现. - 可配置参数 $remote_addr 客户端地址 $rem ...

  7. idea启动java Maven项目,出现" java: 程序包xxxx不存在"

    今天运行Maven项目的时候,出现了,Error:(19, 17) java: 程序包tracetool不存在的情况 本人的解决办法: (1)首先确保maven  pom文件不能报错,即文件上面不能有 ...

  8. 共享访问在.NET中的编程实现

    转载:http://blog.csdn.net/zhzuo/article/details/1732937 共享访问在.NET中的编程实现 发布日期:2007-08-08 | 更新日期:2009-03 ...

  9. 为什么说Java语言是平台无关的?

    适当的整理了一下: 一.平台与机器指令 无论哪种编程语言编写的应用程序都需要经过操作系统和处理器来完成程序的运行,因此这里的平台是又OS和CPU所构成的,所谓的平台无关就是指软件的运行不会因操作系统. ...

  10. mysql 权限管理 grant 命令

    只有root账号可以授权,其他账号不能用grant 授权 mysql> select user(); +----------------+ | user() | +--------------- ...