传送门

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

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

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

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

然而必然会MLE

于是我们只能动态开点

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

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

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

  1 // luogu-judger-enable-o2
  2 //minamoto
  3 #include<bits/stdc++.h>
  4 #define N 300005
  5 using namespace std;
  6 template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
  7 inline int read(){
  8     #define num ch-'0'
  9     char ch;bool flag=0;int res;
 10     while(!isdigit(ch=getchar()))
 11     (ch=='-')&&(flag=true);
 12     for(res=num;isdigit(ch=getchar());res=res*10+num);
 13     (flag)&&(res=-res);
 14     #undef num
 15     return res;
 16 }
 17 int L[N<<2],R[N<<2],mx[N<<2],sum[N<<2];
 18 int sz[N],fa[N],son[N],dfn[N],rk[N],d[N],top[N],val[N],c[N];
 19 int ver[N<<1],head[N],Next[N<<1],yval[N],yc[N];
 20 int rt[N];
 21 int n,m,num,tot,cnt;
 22 inline void add(int u,int v){
 23     ver[++tot]=v,Next[tot]=head[u],head[u]=tot;
 24     ver[++tot]=u,Next[tot]=head[v],head[v]=tot;
 25 }
 26 void dfs1(int u){
 27     sz[u]=1,d[u]=d[fa[u]]+1;
 28     for(int i=head[u];i;i=Next[i]){
 29         if(ver[i]==fa[u]) continue;
 30         int v=ver[i];
 31         fa[v]=u;
 32         dfs1(v);
 33         sz[u]+=sz[v];
 34         if(!son[u]||sz[v]>sz[son[u]]) son[u]=v;
 35     }
 36 }
 37 void dfs2(int u){
 38     if(!top[u]) top[u]=u;
 39     dfn[u]=++num,rk[num]=u;
 40     if(!son[u]) return;
 41     top[son[u]]=top[u],dfs2(son[u]);
 42     for(int i=head[u];i;i=Next[i]){
 43         int v=ver[i];
 44         if(v!=fa[u]&&v!=son[u]) dfs2(v);
 45     }
 46 }
 47 void update(int p){
 48     mx[p]=max(mx[L[p]],mx[R[p]]);
 49     sum[p]=sum[L[p]]+sum[R[p]];
 50 }
 51 void modify(int &p,int l,int r,int k,int v){
 52     if(!p) p=++cnt;
 53     if(l>=r){
 54         mx[p]=sum[p]=v;return;
 55     }
 56     int mid=(l+r)>>1;
 57     if(k<=mid) modify(L[p],l,mid,k,v);
 58     else modify(R[p],mid+1,r,k,v);
 59     update(p);
 60     if(sum[p]==0) p=0;
 61 }
 62 int askmax(int p,int l,int r,int ql,int qr){
 63     if(!p) return -1;
 64     if(ql<=l&&qr>=r) return mx[p];
 65     int mid=(l+r)>>1,val=-1;
 66     if(ql<=mid) cmax(val,askmax(L[p],l,mid,ql,qr));
 67     if(qr>mid) cmax(val,askmax(R[p],mid+1,r,ql,qr));
 68     return val;
 69 }
 70 int asksum(int p,int l,int r,int ql,int qr){
 71     if(!p) return 0;
 72     if(ql<=l&&qr>=r) return sum[p];
 73     int mid=(l+r)>>1,val=0;
 74     if(ql<=mid) val+=asksum(L[p],l,mid,ql,qr);
 75     if(qr>mid) val+=asksum(R[p],mid+1,r,ql,qr);
 76     return val;
 77 }
 78 int path_max(int u,int v){
 79     int ans=-1;
 80     int xz=yc[u];
 81     while(top[u]!=top[v]){
 82         if(d[top[u]]<d[top[v]]) swap(u,v);
 83         cmax(ans,askmax(rt[xz],1,num,dfn[top[u]],dfn[u]));
 84         u=fa[top[u]];
 85     }
 86     if(d[u]<d[v]) swap(u,v);
 87     cmax(ans,askmax(rt[xz],1,num,dfn[v],dfn[u]));
 88     return ans;
 89 }
 90 int path_sum(int u,int v){
 91     int ans=0;
 92     int xz=yc[u];
 93     while(top[u]!=top[v]){
 94         if(d[top[u]]<d[top[v]]) swap(u,v);
 95         ans+=asksum(rt[xz],1,num,dfn[top[u]],dfn[u]);
 96         u=fa[top[u]];
 97     }
 98     if(d[u]<d[v]) swap(u,v);
 99     ans+=asksum(rt[xz],1,num,dfn[v],dfn[u]);
100     return ans;
101 }
102 int main(){
103     //freopen("testdata.in","r",stdin);
104     int n,q;
105     n=read(),q=read();
106     for(int i=1;i<=n;++i)
107     yval[i]=read(),yc[i]=read();
108     for(int i=1;i<n;++i){
109         int u=read(),v=read();
110         add(u,v);
111     }
112     dfs1(1),dfs2(1);
113     for(int i=1;i<=n;++i)
114     modify(rt[yc[rk[i]]],1,num,i,yval[rk[i]]);
115     while(q--){
116         char s[10];int x,y;
117         scanf("%s",s);
118         x=read(),y=read();
119         switch(s[1]){
120             case 'C':{
121                 modify(rt[yc[x]],1,num,dfn[x],0);
122                 yc[x]=y;
123                 modify(rt[yc[x]],1,num,dfn[x],yval[x]);
124                 break;
125             }
126             case 'W':{
127                 yval[x]=y;
128                 modify(rt[yc[x]],1,num,dfn[x],yval[x]);
129                 break;
130             }
131             case 'S':{
132                 printf("%d\n",path_sum(x,y));
133                 break;
134             }
135             case 'M':{
136                 printf("%d\n",path_max(x,y));
137                 break;
138             }
139         }
140     }
141     return 0;
142 }

转载于:https://www.cnblogs.com/bztMinamoto/p/9398077.html

BZOJ3531-[Sdoi2014]旅行(树剖+线段树动态开点)相关推荐

  1. P3292 [SCOI2016]幸运数字(树剖 + 线段树维护线性基)

    P3292 [SCOI2016]幸运数字 思路 如果这题是求x,yx, yx,y之间的距离显然我们可以通过树剖加线段树来写, 但是这里变成了求任意个数的异或最大值.如果给定区间我们显然可以通过线性基来 ...

  2. BZOJ 4817: [Sdoi2017]树点涂色(LCT+树剖+线段树)

    题目描述 Bob有一棵 nn 个点的有根树,其中1号点是根节点.Bob在每个点上涂了颜色,并且每个点上的颜色不同. 定义一条路径的权值是:这条路径上的点(包括起点和终点)共有多少种不同的颜色. Bob ...

  3. BZOJ4034 树上操作(树剖 线段树大模板)

    BZOJ4034 long long 是大坑点 貌似long long 跟int 乘起来会搞事情?... A了这题线段树和树剖的基础OK 嘛 重点过掉的还是线段树区间更新的lazy tag吧 #inc ...

  4. 树剖+线段树||树链剖分||BZOJ1984||Luogu4315||月下“毛景树”

    题面:月下"毛景树" 题解:是道很裸的树剖,但处理的细节有点多(其实是自己线段树没学好).用一个Dfs把边权下移到点权,用E数组记录哪些边被用到了:前三个更新的操作都可以合并起来, ...

  5. 2019ICPC西安邀请赛 E. Tree(树剖 + 线段树)

    Tree 给定一棵树,节点有点权,然后有三种操作: 一.修改1−>s1->s1−>s的路径上的点权与ttt进行按位或. 二.修改1−>s1->s1−>s的路径上的点 ...

  6. ural 1553 树剖+线段树

    //链式前向星版 #include<bits/stdc++.h> using namespace std; const int maxn=100010; //建图 int to[maxn* ...

  7. #HYSBZ3626[LNOI2014]#LCA(经典模型:树剖+线段树维护和)

    3626: [LNOI2014]LCA Time Limit: 10 Sec   Memory Limit: 128 MB Description 给出一个n个节点的有根树(编号为0到n-1,根节点为 ...

  8. 2021 Jiangsu Collegiate Programming Contest F. Jumping Monkey II 树剖+线段树

    F. Jumping Monkey II 题意: 给你 n = 2 e 5 n=2e5 n=2e5的一棵树,每个点有点权 a [ i ] < = 1 e 9 a[i]<=1e9 a[i]& ...

  9. 洛谷2543AHOI2005]航线规划 (树剖+线段树+割边思路)

    这个题的思路还是比较巧妙的. 首先,我们发现操作只有删除和询问两种,而删除并不好维护连通性和割边之类的信息. 所以我们不妨像WC2006水管局长那样,将询问离线,然后把操作转化成加边和询问. 然后,我 ...

最新文章

  1. DevTools 实现原理与性能分析实战
  2. java判断一个单向链表是否有环路
  3. Keras MNIST
  4. oracle导出pdm文件命令,利用PowerDesigner逆向工程导出PDM模型及生成文档
  5. [网络流24题] 航空路线问题 (费用流)
  6. 【转】开机出现 error:file “/boot/grub/i386-pc/normal.mod“ not found 错误提示
  7. 【批处理】windows环境将文件放置在虚拟盘
  8. 年赚133亿!中国平安旗下陆金所向SEC递交招股书
  9. java时间格式转换_Java时间日期格式转换
  10. 我是这样在第一轮筛选简历的
  11. Web Clip 图片变淡变浅变灰解决方案
  12. 分享webStorm汉化
  13. 沙盘模拟软件_三连冠!我校学子连续三年蝉联全国大学生沙盘模拟经营大赛福建省决赛一等奖...
  14. sqlserver用sql语句备份数据库
  15. android模拟机神器[Genymotion]的使用
  16. 【bat】做个一键连接网络打印机的bat
  17. 最有效地戒掉晚睡强迫症(熬夜强迫症、假象失眠症等等)
  18. C# 串口接收的优化处理
  19. Error: Java exception was raised during method invocation
  20. 学以致用——微博文章内容统计分析之一(Excel+GraphLab)

热门文章

  1. PAT 乙级 1003. 我要通过!(20) Java版
  2. 【note】Java程序设计基础第五版(上)
  3. 1050. 螺旋矩阵(25)-PAT乙级真题
  4. 【操作系统】第一章.操作系统引论思维导图
  5. 环形链表得golang实现
  6. 693. Binary Number with Alternating Bits -LeetCode
  7. 并发编程之——写锁源码分析
  8. Jenkins在Linux环境安装
  9. [图示]抢逼围:项目开发3字经
  10. 《Kotlin 程序设计》第十一章 Kotlin实现DSL