传送门

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

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

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

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

然而必然会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,:;}
  7. inline int read(){
  8. #define num ch-'0'
  9. char ch;bool flag=;int res;
  10. while(!isdigit(ch=getchar()))
  11. (ch=='-')&&(flag=true);
  12. for(res=num;isdigit(ch=getchar());res=res*+num);
  13. (flag)&&(res=-res);
  14. #undef num
  15. return res;
  16. }
  17. int L[N<<],R[N<<],mx[N<<],sum[N<<];
  18. int sz[N],fa[N],son[N],dfn[N],rk[N],d[N],top[N],val[N],c[N];
  19. int ver[N<<],head[N],Next[N<<],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]=,d[u]=d[fa[u]]+;
  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)>>;
  57. if(k<=mid) modify(L[p],l,mid,k,v);
  58. else modify(R[p],mid+,r,k,v);
  59. update(p);
  60. if(sum[p]==) p=;
  61. }
  62. int askmax(int p,int l,int r,int ql,int qr){
  63. if(!p) return -;
  64. if(ql<=l&&qr>=r) return mx[p];
  65. int mid=(l+r)>>,val=-;
  66. if(ql<=mid) cmax(val,askmax(L[p],l,mid,ql,qr));
  67. if(qr>mid) cmax(val,askmax(R[p],mid+,r,ql,qr));
  68. return val;
  69. }
  70. int asksum(int p,int l,int r,int ql,int qr){
  71. if(!p) return ;
  72. if(ql<=l&&qr>=r) return sum[p];
  73. int mid=(l+r)>>,val=;
  74. if(ql<=mid) val+=asksum(L[p],l,mid,ql,qr);
  75. if(qr>mid) val+=asksum(R[p],mid+,r,ql,qr);
  76. return val;
  77. }
  78. int path_max(int u,int v){
  79. int ans=-;
  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],,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],,num,dfn[v],dfn[u]));
  88. return ans;
  89. }
  90. int path_sum(int u,int v){
  91. int ans=;
  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],,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],,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=;i<=n;++i)
  107. yval[i]=read(),yc[i]=read();
  108. for(int i=;i<n;++i){
  109. int u=read(),v=read();
  110. add(u,v);
  111. }
  112. dfs1(),dfs2();
  113. for(int i=;i<=n;++i)
  114. modify(rt[yc[rk[i]]],,num,i,yval[rk[i]]);
  115. while(q--){
  116. char s[];int x,y;
  117. scanf("%s",s);
  118. x=read(),y=read();
  119. switch(s[]){
  120. case 'C':{
  121. modify(rt[yc[x]],,num,dfn[x],);
  122. yc[x]=y;
  123. modify(rt[yc[x]],,num,dfn[x],yval[x]);
  124. break;
  125. }
  126. case 'W':{
  127. yval[x]=y;
  128. modify(rt[yc[x]],,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 ;
  142. }

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. Android开发实战之ViewPager的轮播

    在安卓开发的许多控件中,如果你没有使用过ViewPager,就不能算是一个安卓开发工程师,在本篇博文中,我会总结ViewPager的使用方法, 以及一些开发中的拓展.希望本篇博文对你的学习和工作有所帮 ...

  2. NoSuchBeanDefinitionException:No qualifying bean of type found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency.

    报错如下: NoSuchBeanDefinitionException:No qualifying bean of type   found for dependency: expected at l ...

  3. 32. Longest Valid Parentheses (Stack; DP)

    Given a string containing just the characters '(' and ')', find the length of the longest valid (wel ...

  4. Ros学习——Cmakelists.txt文件解读

    1.过程 .Required CMake Version (cmake_minimum_required) //CMake 需要的版本 .Package Name (project()) //#定义工 ...

  5. 大话CNN

    这几年深度学习快速发展,在图像识别.语音识别.物体识别等各种场景上取得了巨大的成功,例如AlphaGo击败世界围棋冠军,iPhone X内置了人脸识别解锁功能等等,很多AI产品在世界上引起了很大的轰动 ...

  6. SVO详细解读

    SVO详细解读 极品巧克力 前言 接上一篇文章<深度滤波器详细解读>. SVO(Semi-Direct Monocular Visual Odometry)是苏黎世大学Scaramuzza ...

  7. Mysql蠕虫复制

    将查询出来的数据插入到指定表中,形如: INSERT into user_info(version,create_user_count,create_pc_count) select version, ...

  8. [C++] Memory Retrieval(内存检索)

    Traverse the memory by  (char*) , because every time it will increase by 1byte when i want get the i ...

  9. code1173 最优贸易

    先正向从1点出发SPFA,获得min[i],就是到达i点能最低购买到的价格,(起始点到i的路上经过的最小值) 然后反向(将图反向),从n点开始SPFA,获得max[i],就是从i点到终点能够卖出的最大 ...

  10. Spring.net 事件的注入

    1.首先上客户端代码 static void Main(string[] args)        {            IApplicationContext ctx = ContextRegi ...