传送门

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

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

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

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

然而必然会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. Scala基础:面向对象之trait

    trait类似于java中的interface,但是有所不同 Scala中的trait是一种特殊的概念: 首先先将trait作为接口使用,此时的trait就与Java中的接口 (interface)非 ...

  2. 【bzoj2242】[SDOI2011]计算器

    2242: [SDOI2011]计算器 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 3207  Solved: 1258[Submit][Statu ...

  3. Spring Data JPA + layui的前台分页插件layPage实现页面的分页

    一.后台代码: 1.1 controller层代码 @RequestMapping("/xxxxxx") public String showInformationCode(Str ...

  4. 微信小程序(应用号)开发教程

    本文档将带你一步步创建完成一个微信小程序,并可以在手机上体验该小程序的实际效果.这个小程序的首页将会显示欢迎语以及当前用户的微信头像,点击头像,可以在新开的页面中查看当前小程序的启动日志.下载源码 1 ...

  5. 转载 MYSQL性能优化的最佳20+条经验

    转自:https://coolshell.cn/articles/1846.html 今天,数据库的操作越来越成为整个应用的性能瓶颈了,这点对于Web应用尤其明显.关于数据库的性能,这并不只是DBA才 ...

  6. code1225 八数码Bfs

    Bfs搜索 1.把棋盘直接作为状态: #include<iostream> #include<cstring> #include<queue> #include&l ...

  7. linux下两台服务器文件实时同步方案实现-乾颐堂

    假设有如下需求: 假设两个服务器: 192.168.0.1 源服务器  有目录 /opt/test/ 192.168.0.2 目标服务器  有目录 /opt/bak/test/ 实现的目的就是保持这两 ...

  8. Use formatter to format your JAVA code

    In order to make the codes looks unified and make it easy to understand, it's better to use the same ...

  9. Spring.net页面属性注入

    .条件spring.web程序集 1.1 system.web配置 <httpHandlers> <add verb="*" path="*.aspx& ...

  10. RAW编程接口

    LWIP移植好之后,就要使用它提供的API接口来编写程序.