题目大意:

一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w

我们将以下面的形式来要求你对这棵树完成一些操作:

I. CHANGE u t : 把结点u的权值改为t

II. QMAX u v: 询问从点u到点v的路径上的节点的最大权值

III. QSUM u v: 询问从点u到点v的路径上的节点的权值和 注意:从点u到点v的路径上的节点包括u和v本身

思路:

树链剖分

衣服都不穿的

搞到线段树里,然后维护维护

背一背代码

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cmath>
  4. #include<cstdlib>
  5. #include<cstring>
  6. #include<algorithm>
  7. #include<vector>
  8. #include<queue>
  9. #define inf 2139062143
  10. #define ll long long
  11. #define MAXN 30101
  12. #define MOD
  13. using namespace std;
  14. inline int read()
  15. {
  16. int x=,f=;char ch=getchar();
  17. while(!isdigit(ch)) {if(ch=='-') f=-;ch=getchar();}
  18. while(isdigit(ch)) {x=x*+ch-'';ch=getchar();}
  19. return x*f;
  20. }
  21. int n,Cnt,nxt[MAXN*],fst[MAXN],to[MAXN*],val[MAXN];
  22. int fa[MAXN],dep[MAXN],bl[MAXN],cnt[MAXN],hsh[MAXN];
  23. struct data{int mx,sum,l,r;}tr[MAXN*];
  24. void add(int u,int v) {nxt[++Cnt]=fst[u],fst[u]=Cnt,to[Cnt]=v;}
  25. void build(int x)
  26. {
  27. for(int i=fst[x];i;i=nxt[i])
  28. {
  29. if(to[i]==fa[x]) continue;
  30. dep[to[i]]=dep[x]+;
  31. fa[to[i]]=x;
  32. build(to[i]);
  33. cnt[x]+=cnt[to[i]];
  34. }
  35. cnt[x]++;
  36. }
  37. void Build(int x,int chn)
  38. {
  39. int hvs=;hsh[x]=++Cnt,bl[x]=chn;
  40. for(int i=fst[x];i;i=nxt[i])
  41. if(fa[x]!=to[i]&&cnt[hvs]<cnt[to[i]]) hvs=to[i];
  42. if(!hvs) return ;
  43. Build(hvs,chn);
  44. for(int i=fst[x];i;i=nxt[i])
  45. if(fa[x]!=to[i]&&hvs!=to[i]) Build(to[i],to[i]);
  46. }
  47. void s_build(int k,int l,int r)
  48. {
  49. tr[k].l=l,tr[k].r=r;
  50. if(l==r) return ;
  51. int mid=(l+r)>>;
  52. s_build(k<<,l,mid);
  53. s_build(k<<|,mid+,r);
  54. }
  55. void upd(int k,int pos,int x)
  56. {;
  57. int l=tr[k].l,r=tr[k].r;
  58. if(l==r) {tr[k].mx=tr[k].sum=x;return ;}
  59. int mid=(l+r)>>;
  60. if(mid>=pos) upd(k<<,pos,x);
  61. else upd(k<<|,pos,x);
  62. tr[k].mx=max(tr[k<<].mx,tr[k<<|].mx);
  63. tr[k].sum=tr[k<<].sum+tr[k<<|].sum;
  64. }
  65. int q_sum(int k,int a,int b)
  66. {
  67. int l=tr[k].l,r=tr[k].r;
  68. if(l==a&&r==b) return tr[k].sum;
  69. int mid=(l+r)>>;
  70. if(b<=mid) return q_sum(k<<,a,b);
  71. if(a>mid) return q_sum(k<<|,a,b);
  72. else return q_sum(k<<,a,mid)+q_sum(k<<|,mid+,b);
  73. }
  74. int q_mx(int k,int a,int b)
  75. {
  76. int l=tr[k].l,r=tr[k].r;
  77. if(l==a&&r==b) return tr[k].mx;
  78. int mid=(l+r)>>;
  79. if(b<=mid) return q_mx(k<<,a,b);
  80. if(a>mid) return q_mx(k<<|,a,b);
  81. else return max(q_mx(k<<,a,mid),q_mx(k<<|,mid+,b));
  82. }
  83. int main()
  84. {
  85. n=read();int a,b,res;
  86. for(int i=;i<n;i++) {a=read(),b=read();add(a,b);add(b,a);}
  87. for(int i=;i<=n;i++) val[i]=read();fa[]=;
  88. build();Cnt=;
  89. Build(,);
  90. s_build(,,n);
  91. for(int i=;i<=n;i++) upd(,hsh[i],val[i]);
  92. int T=read();
  93. char ch[];
  94. while(T--)
  95. {
  96. scanf("%s",ch);a=read(),b=read();
  97. if(ch[]=='C') {val[a]=b;upd(,hsh[a],b);}
  98. else if(ch[]=='M')
  99. {
  100. res=-inf;
  101. while(bl[a]!=bl[b])
  102. {
  103. if(dep[bl[a]]<dep[bl[b]]) swap(a,b);
  104. res=max(res,q_mx(,hsh[bl[a]],hsh[a]));
  105. a=fa[bl[a]];
  106. }
  107. res=max(res,q_mx(,min(hsh[a],hsh[b]),max(hsh[a],hsh[b])));
  108. printf("%d\n",res);
  109. }
  110. else if(ch[]=='S')
  111. {
  112. res=;
  113. while(bl[a]!=bl[b])
  114. {
  115. if(dep[bl[a]]<dep[bl[b]]) swap(a,b);
  116. res+=q_sum(,hsh[bl[a]],hsh[a]);
  117. a=fa[bl[a]];
  118. }
  119. res+=q_sum(,min(hsh[a],hsh[b]),max(hsh[a],hsh[b]));
  120. printf("%d\n",res);
  121. }
  122. }
  123. }

UPD 2018.9.19

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<algorithm>
  4. #include<cmath>
  5. #include<cstring>
  6. #include<cstdlib>
  7. #include<set>
  8. #include<map>
  9. #include<vector>
  10. #include<stack>
  11. #include<queue>
  12. #define ll long long
  13. #define inf 2147383611
  14. #define MAXN 500100
  15. using namespace std;
  16. inline int read()
  17. {
  18. int x=,f=;
  19. char ch;ch=getchar();
  20. while(!isdigit(ch)) {if(ch=='-') f=-;ch=getchar();}
  21. while(isdigit(ch)) {x=x*+ch-'';ch=getchar();}
  22. return x*f;
  23. }
  24. int n,cnt,nxt[MAXN<<],fst[MAXN],to[MAXN<<],val[MAXN];
  25. int fa[MAXN],dep[MAXN],bl[MAXN],sz[MAXN],hsh[MAXN],mx[MAXN<<],sum[MAXN<<];
  26. void add(int u,int v) {nxt[++cnt]=fst[u],fst[u]=cnt,to[cnt]=v;}
  27. void dfs(int x)
  28. {
  29. sz[x]=,dep[x]=dep[fa[x]]+;
  30. for(int i=fst[x];i;i=nxt[i])
  31. if(to[i]!=fa[x]) {fa[to[i]]=x;dfs(to[i]);sz[x]+=sz[to[i]];}
  32. }
  33. void Dfs(int x,int anc)
  34. {
  35. hsh[x]=++cnt,bl[x]=anc;int hvs=;
  36. for(int i=fst[x];i;i=nxt[i])
  37. if(dep[to[i]]>dep[x]&&sz[hvs]<sz[to[i]]) hvs=to[i];
  38. if(!hvs) return ;Dfs(hvs,anc);
  39. for(int i=fst[x];i;i=nxt[i])
  40. if(dep[to[i]]>dep[x]&&to[i]!=hvs) {Dfs(to[i],to[i]);}
  41. }
  42. void mdf(int k,int l,int r,int x,int w)
  43. {
  44. if(l==r) {mx[k]=sum[k]=w;return ;}
  45. int mid=(l+r)>>;
  46. if(x<=mid) mdf(k<<,l,mid,x,w);
  47. else mdf(k<<|,mid+,r,x,w);
  48. mx[k]=max(mx[k<<],mx[k<<|]),sum[k]=sum[k<<]+sum[k<<|];
  49. }
  50. int querys(int k,int l,int r,int a,int b)
  51. {
  52. if(l==a&&r==b) return sum[k];
  53. int mid=(l+r)>>;
  54. if(b<=mid) return querys(k<<,l,mid,a,b);
  55. else if(a>mid) return querys(k<<|,mid+,r,a,b);
  56. else return querys(k<<,l,mid,a,mid)+querys(k<<|,mid+,r,mid+,b);
  57. }
  58. int querym(int k,int l,int r,int a,int b)
  59. {
  60. if(l==a&&r==b) return mx[k];
  61. int mid=(l+r)>>;
  62. if(b<=mid) return querym(k<<,l,mid,a,b);
  63. else if(a>mid) return querym(k<<|,mid+,r,a,b);
  64. else return max(querym(k<<,l,mid,a,mid),querym(k<<|,mid+,r,mid+,b));
  65. }
  66. int main()
  67. {
  68. n=read();int a,b,res,T;char ch[];
  69. for(int i=;i<n;i++) {a=read(),b=read();add(a,b);add(b,a);}
  70. dfs();cnt=;Dfs(,);
  71. for(int i=;i<=n;i++) mdf(,,n,hsh[i],read());
  72. T=read();
  73. while(T--)
  74. {
  75. scanf("%s",ch);a=read(),b=read();
  76. if(ch[]=='C') mdf(,,n,hsh[a],b);
  77. else if(ch[]=='M')
  78. {
  79. res=-inf;
  80. while(bl[a]!=bl[b])
  81. {
  82. if(dep[bl[a]]<dep[bl[b]]) swap(a,b);
  83. res=max(res,querym(,,n,hsh[bl[a]],hsh[a]));
  84. a=fa[bl[a]];
  85. }
  86. res=max(res,querym(,,n,min(hsh[a],hsh[b]),max(hsh[a],hsh[b])));
  87. printf("%d\n",res);
  88. }
  89. else if(ch[]=='S')
  90. {
  91. res=;
  92. while(bl[a]!=bl[b])
  93. {
  94. if(dep[bl[a]]<dep[bl[b]]) swap(a,b);
  95. res+=querys(,,n,hsh[bl[a]],hsh[a]);
  96. a=fa[bl[a]];
  97. }
  98. res+=querys(,,n,min(hsh[a],hsh[b]),max(hsh[a],hsh[b]));
  99. printf("%d\n",res);
  100. }
  101. }
  102. }

bzoj 1036 树的统计Count的更多相关文章

  1. BZOJ 1036 树的统计Count 树链剖分模板题

    题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=1036 题目大意: 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将 ...

  2. [置顶] bzoj 1036 树的统计Count 点权值模板

    树链剖分 点权型可做模板,链路剖分的思想把点hash到线段树的上,然后可通过n*(log(n)*log(n))的复杂度在树上操作,在线段树上能操作的在链路上都能操作. #include<cstd ...

  3. BZOJ - 1036 树的统计Count (LCT)

    LCT试炼题(代码量居然完爆树剖?) #include<bits/stdc++.h> using namespace std; ,inf=0x3f3f3f3f; ],flp[N],n,m, ...

  4. BZOJ - 1036 树的统计Count (树链剖分+线段树)

    题目链接 #include<bits/stdc++.h> using namespace std; typedef long long ll; ,inf=0x3f3f3f3f; ],mx[ ...

  5. BZOJ 1036 树的统计-树链剖分

    [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 12904 Solved: 5191[Submit][Status ...

  6. Codevs 2460 == BZOJ 1036 树的统计

     2460 树的统计 2008年省队选拔赛浙江 时间限制: 2 s 空间限制: 128000 KB 题目等级 : 大师 Master 题目描述 Description 一棵树上有n个节点,编号分别为1 ...

  7. BZOJ 1036 树的统计

    Description 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把结点u的权值改为t II. Q ...

  8. HYSBZ 1036 树的统计Count(树链剖分)题解

    思路: 树链剖分,不知道说什么...我连模板都不会用 代码: #include<map> #include<ctime> #include<cmath> #incl ...

  9. BZOJ 1036 树的统计(树链剖分)

    点权树链剖分模板题. # include <cstdio> # include <cstring> # include <cstdlib> # include &l ...

随机推荐

  1. django在验证登录页面时遇到的数据查询问题

    数据库查询时针对不存在的用户名进行验证 django在查询数据库时,可以使用get和filter两种方法. 两者的区别 当数据库内不存在该数据时,get会返回异常,而filter会返回空. 当数据库内 ...

  2. TWaver 3D应用于大型数据中心(续)

    在2014年11月份,我们当时发了一篇有关TWaver HTML5 3D应用于大型数据中心的文章,该blog比较详细的描述一些常用的功能的实现方法,比如:动态添加机柜,告警,温度,湿度等相关的功能的具 ...

  3. 25款css动画库

    http://www.swiper.com.cn/usage/animate/index.html   //swiper https://cssanimation.io/ http://ianlunn ...

  4. Python学习-if条件语句

    Python条件语句是通过一条或多条语句的执行结果(True或者False)来决定执行的代码块. 单分支条件语句 if 判断条件: 条件成立,执行该代码块.... 注意:与其他编程语言,如Java和C ...

  5. ubuntu环境搭建DNS服务器

    1 安装bind9 apt install bind9 2 修改 named.conf.local,添加要解析的域名及对应的域名配置文件 zone "test.cn"{ type ...

  6. buf.readUInt16BE()

    buf.readUInt16BE(offset[, noAssert]) buf.readUInt16LE(offset[, noAssert]) offset {Number} 0 <= of ...

  7. 08 Python基础数据结构

    目录: 1) 列表 2) 元组 3) 字符串 4) bytes 5) bytearray 6) 字典 7) 集合 8) 冻集合 """1. 列表特性2. 创建3. 增加4 ...

  8. codeforces 372 Complete the Word(双指针)

    codeforces 372 Complete the Word(双指针) 题链 题意:给出一个字符串,其中'?'代表这个字符是可变的,要求一个连续的26位长的串,其中每个字母都只出现一次 #incl ...

  9. BNUOJ 33895 D-City

    D-City Time Limit: 1000ms Memory Limit: 65535KB This problem will be judged on HDU. Original ID: 449 ...

  10. 控制公司(codevs 2051)

    题目描述 Description 有些公司是其他公司的部分拥有者,因为他们获得了其他公司发行的股票的一部分.例如,福特公司拥有马自达公司12%的股票.据说,如果至少满足了以下三个条件之一,公司A就可以 ...