传送门

完了今天才知道原来线段树的动态开点和主席树是不一样的啊

我们先考虑没有宗教信仰的限制,那么就是一个很明显的树剖+线段树,路径查询最大值以及路径和

然后有了宗教信仰的限制该怎么做呢?

先考虑暴力,对每一个信仰建一棵线段树

然而必然会MLE

于是我们只能动态开点

说一下我自己的理解吧,动态开点就是把那些建树过程中没有用的节点删去,以此来节省空间

比如当$sum[p]=0$时,直接删去点$p$

具体实现还是参考一下代码吧

 // luogu-judger-enable-o2
//minamoto
#include<bits/stdc++.h>
#define N 300005
using namespace std;
template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,:;}
inline int read(){
#define num ch-'0'
char ch;bool flag=;int res;
while(!isdigit(ch=getchar()))
(ch=='-')&&(flag=true);
for(res=num;isdigit(ch=getchar());res=res*+num);
(flag)&&(res=-res);
#undef num
return res;
}
int L[N<<],R[N<<],mx[N<<],sum[N<<];
int sz[N],fa[N],son[N],dfn[N],rk[N],d[N],top[N],val[N],c[N];
int ver[N<<],head[N],Next[N<<],yval[N],yc[N];
int rt[N];
int n,m,num,tot,cnt;
inline void add(int u,int v){
ver[++tot]=v,Next[tot]=head[u],head[u]=tot;
ver[++tot]=u,Next[tot]=head[v],head[v]=tot;
}
void dfs1(int u){
sz[u]=,d[u]=d[fa[u]]+;
for(int i=head[u];i;i=Next[i]){
if(ver[i]==fa[u]) continue;
int v=ver[i];
fa[v]=u;
dfs1(v);
sz[u]+=sz[v];
if(!son[u]||sz[v]>sz[son[u]]) son[u]=v;
}
}
void dfs2(int u){
if(!top[u]) top[u]=u;
dfn[u]=++num,rk[num]=u;
if(!son[u]) return;
top[son[u]]=top[u],dfs2(son[u]);
for(int i=head[u];i;i=Next[i]){
int v=ver[i];
if(v!=fa[u]&&v!=son[u]) dfs2(v);
}
}
void update(int p){
mx[p]=max(mx[L[p]],mx[R[p]]);
sum[p]=sum[L[p]]+sum[R[p]];
}
void modify(int &p,int l,int r,int k,int v){
if(!p) p=++cnt;
if(l>=r){
mx[p]=sum[p]=v;return;
}
int mid=(l+r)>>;
if(k<=mid) modify(L[p],l,mid,k,v);
else modify(R[p],mid+,r,k,v);
update(p);
if(sum[p]==) p=;
}
int askmax(int p,int l,int r,int ql,int qr){
if(!p) return -;
if(ql<=l&&qr>=r) return mx[p];
int mid=(l+r)>>,val=-;
if(ql<=mid) cmax(val,askmax(L[p],l,mid,ql,qr));
if(qr>mid) cmax(val,askmax(R[p],mid+,r,ql,qr));
return val;
}
int asksum(int p,int l,int r,int ql,int qr){
if(!p) return ;
if(ql<=l&&qr>=r) return sum[p];
int mid=(l+r)>>,val=;
if(ql<=mid) val+=asksum(L[p],l,mid,ql,qr);
if(qr>mid) val+=asksum(R[p],mid+,r,ql,qr);
return val;
}
int path_max(int u,int v){
int ans=-;
int xz=yc[u];
while(top[u]!=top[v]){
if(d[top[u]]<d[top[v]]) swap(u,v);
cmax(ans,askmax(rt[xz],,num,dfn[top[u]],dfn[u]));
u=fa[top[u]];
}
if(d[u]<d[v]) swap(u,v);
cmax(ans,askmax(rt[xz],,num,dfn[v],dfn[u]));
return ans;
}
int path_sum(int u,int v){
int ans=;
int xz=yc[u];
while(top[u]!=top[v]){
if(d[top[u]]<d[top[v]]) swap(u,v);
ans+=asksum(rt[xz],,num,dfn[top[u]],dfn[u]);
u=fa[top[u]];
}
if(d[u]<d[v]) swap(u,v);
ans+=asksum(rt[xz],,num,dfn[v],dfn[u]);
return ans;
}
int main(){
//freopen("testdata.in","r",stdin);
int n,q;
n=read(),q=read();
for(int i=;i<=n;++i)
yval[i]=read(),yc[i]=read();
for(int i=;i<n;++i){
int u=read(),v=read();
add(u,v);
}
dfs1(),dfs2();
for(int i=;i<=n;++i)
modify(rt[yc[rk[i]]],,num,i,yval[rk[i]]);
while(q--){
char s[];int x,y;
scanf("%s",s);
x=read(),y=read();
switch(s[]){
case 'C':{
modify(rt[yc[x]],,num,dfn[x],);
yc[x]=y;
modify(rt[yc[x]],,num,dfn[x],yval[x]);
break;
}
case 'W':{
yval[x]=y;
modify(rt[yc[x]],,num,dfn[x],yval[x]);
break;
}
case 'S':{
printf("%d\n",path_sum(x,y));
break;
}
case 'M':{
printf("%d\n",path_max(x,y));
break;
}
}
}
return ;
}

BZOJ3531-[Sdoi2014]旅行(树剖+线段树动态开点)的更多相关文章

  1. 【BZOJ5210】最大连通子块和 树剖线段树+动态DP

    [BZOJ5210]最大连通子块和 Description 给出一棵n个点.以1为根的有根树,点有点权.要求支持如下两种操作: M x y:将点x的点权改为y: Q x:求以x为根的子树的最大连通子块 ...

  2. BZOJ_2238_Mst_树剖+线段树

    BZOJ_2238_Mst_树剖+线段树 Description 给出一个N个点M条边的无向带权图,以及Q个询问,每次询问在图中删掉一条边后图的最小生成树.(各询问间独立,每次询问不对之后的询问产生影 ...

  3. BZOJ_4551_[Tjoi2016&Heoi2016]树_树剖+线段树

    BZOJ_4551_[Tjoi2016&Heoi2016]树_树剖+线段树 Description 在2016年,佳媛姐姐刚刚学习了树,非常开心.现在他想解决这样一个问题:给定一颗有根树(根为 ...

  4. BZOJ_2157_旅游_树剖+线段树

    BZOJ_2157_旅游_树剖+线段树 Description Ray 乐忠于旅游,这次他来到了T 城.T 城是一个水上城市,一共有 N 个景点,有些景点之间会用一座桥连接.为了方便游客到达每个景点但 ...

  5. [LNOI2014]LCA(树剖+线段树)

    \(\%\%\% Fading\) 此题是他第一道黑题(我的第一道黑题是蒲公英) 一直不敢开,后来发现是差分一下,将询问离线,树剖+线段树维护即可 \(Code\ Below:\) #include ...

  6. [CF1007D]Ants[2-SAT+树剖+线段树优化建图]

    题意 我们用路径 \((u, v)\) 表示一棵树上从结点 \(u\) 到结点 \(v\) 的最短路径. 给定一棵由 \(n\) 个结点构成的树.你需要用 \(m\) 种不同的颜色为这棵树的树边染色, ...

  7. LOJ#3088. 「GXOI / GZOI2019」旧词(树剖+线段树)

    题面 传送门 题解 先考虑\(k=1\)的情况,我们可以离线处理,从小到大对于每一个\(i\),令\(1\)到\(i\)的路径上每个节点权值增加\(1\),然后对于所有\(x=i\)的询问查一下\(y ...

  8. 【bzoj4699】树上的最短路(树剖+线段树优化建图)

    题意 给你一棵 $n$ 个点 $n-1$ 条边的树,每条边有一个通过时间.此外有 $m$ 个传送条件 $(x_1,y_1,x_2,y_2,c)$,表示从 $x_1$ 到 $x_2$ 的简单路径上的点可 ...

  9. POJ3237 Tree(树剖+线段树+lazy标记)

    You are given a tree with N nodes. The tree’s nodes are numbered 1 through N and its edges are numbe ...

随机推荐

  1. Bug of VS2015+WDK

    1>  Signability test failed.1>  1>  Errors:1>  22.9.7: DriverVer set to incorrect date ( ...

  2. 【UVA1515 算法竞赛入门指南】 水塘【最小割】

    题意: 输入一个h行w列的字符矩阵,草地用“#”表示,洞用"."表示.你可以把草改成洞,每格花费为d,也可以把洞填上草,每格花费为f.最后还需要在草和洞之间修围栏,每条边花费为b. ...

  3. Mesos的资源分配

    Apache Mesos能够成为最优秀的数据中心资源管理器的一个重要功能是面对各种类型的应用,它具备像交警一样的疏导能力.本文将深入Mesos的资源分配内部, 探讨Mesos是如何根据客户应用需求,平 ...

  4. haproxy 配置 说明

    一.环境说明实验环境OS CentOS5.4192.168.0.14    proxy192.168.0.24    web1192.168.0.64    web2 官方地址:http://hapr ...

  5. 常见的APP性能测试指标

    性能测试在软件的质量保证中起着重要的作用,它包括的测试内容丰富多样.中国软件评测中心将性能测试概括为三个方面:应用在客户端性能的测试.应用在网络上性能的测试和应用在服务器端性能的测试.通常情况下,三方 ...

  6. 服务器安装Ubuntu的那些坑

    1. 虽然简体中文很亲切,但请选择English,否则极有可能安装途中报错 2. 安装完各种系统文件后,请注意选择启动Disk,一不小心跳过了貌似只好重装 3. 进入后无法使用apt-get,总提示需 ...

  7. CentOS搭建VSFTP服务器

    一.安装vsftpd 1.查看是否已经安装vsftpd 2.如果没有,就安装 3.测试是否安装成功 4.安装成功设置开机启动 二.配置vsftpd 1.修改配置文件/etc/vsftpd/vsftpd ...

  8. Zookeeper使用--Java API

    1  创建节点 创建节点有异步和同步两种方式.无论是异步或者同步,Zookeeper都不支持递归调用,即无法在父节点不存在的情况下创建一个子节点,如在/zk-ephemeral节点不存在的情况下创建/ ...

  9. Spring Boot☞ 使用Spring-data-jpa简化数据访问层

    效果图: 代码区: package com.wls.integrateplugs.jpa.primary.model; /** * Created by wls on 2017/8/24. */ im ...

  10. Selenium模拟浏览器初识

    Seleniumd介绍 在写Python爬虫的时候,最麻烦的不是那些海量的静态网站,而是那些通过JavaScript获取数据的站点.Python本身对js的支持不好,所以就有良心的开发者来做贡献了,这 ...