传送门

题目描述

Our protagonist is the handsome human prince Aragorn comes from The Lord of the Rings. One day Aragorn finds a lot of enemies who want to invade his kingdom. As Aragorn knows, the enemy has N camps out of his kingdom and M edges connect them. It is guaranteed that for any two camps, there is one and only one path connect them. At first Aragorn know the number of enemies in every camp.

But the enemy is cunning , they will increase or decrease the number of soldiers in camps. Every time the enemy change the number of soldiers, they will set two camps C1 and C2. Then, for C1, C2 and all camps on the path from C1 to C2, they will increase or decrease K soldiers to these camps. Now Aragorn wants to know the number of soldiers in some particular camps real-time.

题目大意

三种操作:

  • 点\(x\)到点\(y\)的路径上的每一个点的权值都+\(v\)
  • 点\(x\)到点\(y\)的路径上的每一个点的权值都-\(v\)
  • 查询点\(u\)的权值

解法

树链剖分的模板题,拿过来随便练练手。

我会在第4将的xio讲堂上详细讲解树剖,这里就稍微介绍一下。

树剖在沃的理解上,就是将一棵树通过dfs序或者其他的顺序,和轻重关系来展开到一个一位数组中,然后我们将各个在树上的操作变成一位的操作,这种操作就只需要用数据结构来维护就可以了。

那么反观这道题,我们就将树展开到一维上,并且用线段树来维护,其实非常好理解。

ac代码

  1. #include<bits/stdc++.h>
  2. #define ms(a,b) memset(a,b,sizeof(a))
  3. #define N 50005
  4. #define M 50005
  5. using namespace std;
  6. struct edge{
  7. int to,nt;
  8. }E[M<<1];
  9. int H[N],a[N],val[N],sz[N],dep[N],son[N],top[N],idx[N],fa[N];
  10. int cnt,tot,n,m,p;
  11. int read(){
  12. int w=0,x=0;char ch=0;
  13. while(!isdigit(ch))w|=ch=='-',ch=getchar();
  14. while(isdigit(ch))x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
  15. return w?-x:x;
  16. }
  17. void addedge(int u,int v){
  18. E[++cnt]=(edge){v,H[u]}; H[u]=cnt;
  19. }
  20. struct segment_tree{//线段树的各个操作,比较简单不多做讲解
  21. #define lson (nod<<1)
  22. #define rson (nod<<1|1)
  23. #define mid (l+r>>1)
  24. int tr[N<<2],add[N<<2];
  25. void init(){
  26. ms(tr,0);ms(add,0);
  27. }
  28. void pushup(int nod){
  29. tr[nod]=tr[lson]+tr[rson];
  30. }
  31. void pushdown(int l,int r,int nod){
  32. if(!add[nod]) return;
  33. tr[lson]+=add[nod]*(mid-l+1);
  34. tr[rson]+=add[nod]*(r-mid);
  35. add[lson]+=add[nod];
  36. add[rson]+=add[nod];
  37. add[nod]=0;
  38. }
  39. void build(int l,int r,int nod,int *a){
  40. if(l>=r){
  41. tr[nod]=a[l];
  42. return;
  43. }
  44. build(l,mid,lson,a);
  45. build(mid+1,r,rson,a);
  46. pushup(nod);
  47. }
  48. void update(int l,int r,int ql,int qr,int v,int nod){
  49. if(ql<=l&&r<=qr){
  50. tr[nod]+=v*(r-l+1);
  51. add[nod]+=v;
  52. return;
  53. }
  54. pushdown(l,r,nod);
  55. if(ql<=mid) update(l,mid,ql,qr,v,lson);
  56. if(qr>mid) update(mid+1,r,ql,qr,v,rson);
  57. pushup(nod);
  58. }
  59. int query(int l,int r,int k,int nod){
  60. if(l==r) return tr[nod];
  61. pushdown(l,r,nod);
  62. if(k<=mid) return query(l,mid,k,lson);
  63. else return query(mid+1,r,k,rson);
  64. }
  65. }T;
  66. void dfs1(int u,int ft,int dp){//第一遍dfs,求出sz,fa,dep。
  67. sz[u]=1;
  68. fa[u]=ft;
  69. dep[u]=dp;
  70. int maxson=-1;
  71. for(int e=H[u];e;e=E[e].nt){
  72. int v=E[e].to;
  73. if(v==fa[u]) continue;
  74. dfs1(v,u,dp+1);
  75. sz[u]+=sz[v];
  76. if(sz[v]>maxson) maxson=sz[v],son[u]=v;
  77. }
  78. }
  79. void dfs2(int u,int tp){//第二遍dfs,求出idx,val,top,和将各个重点连成重边
  80. idx[u]=++tot;
  81. val[tot]=a[u];
  82. top[u]=tp;
  83. if(!son[u]) return;
  84. dfs2(son[u],tp);
  85. for(int e=H[u];e;e=E[e].nt){
  86. int v=E[e].to;
  87. if(v==fa[u]||v==son[u]) continue;
  88. dfs2(v,v);
  89. }
  90. }
  91. void init(){
  92. cnt=0,tot=0;
  93. ms(son,0);ms(E,0);ms(H,0);ms(top,0);ms(sz,0);ms(idx,0);ms(val,0);
  94. }
  95. int point_query(int u){return T.query(1,n,idx[u],1);}
  96. void chain_update(int u,int v,int w){
  97. while(top[u]!=top[v]){
  98. if(dep[top[u]]<dep[top[v]]) swap(u,v);
  99. T.update(1,n,idx[top[u]],idx[u],w,1);
  100. u=fa[top[u]];
  101. }
  102. if(dep[u]>dep[v]) swap(u,v);
  103. T.update(1,n,idx[u],idx[v],w,1);
  104. }
  105. int main(){
  106. while(~scanf("%d%d%d",&n,&m,&p)){
  107. T.init(); init();
  108. for(int i=1;i<=n;i++) a[i]=read();
  109. for(int i=1;i<=m;i++) {
  110. int u=read(),v=read();
  111. addedge(u,v);
  112. addedge(v,u);
  113. }
  114. dfs1(1,-1,1);
  115. dfs2(1,1);
  116. T.build(1,n,1,val);
  117. while(p--){
  118. char opt[5];
  119. scanf("%s",opt);
  120. if(opt[0]=='Q'){
  121. int x=read();
  122. printf("%d\n",point_query(x));
  123. }
  124. if(opt[0]=='I'){
  125. int x=read(),y=read(),z=read();
  126. chain_update(x,y,z);
  127. }
  128. if(opt[0]=='D'){
  129. int x=read(),y=read(),z=read();
  130. chain_update(x,y,-z);
  131. }
  132. }
  133. }
  134. return 0;
  135. }

[hdu3966]Aragorn's Story的更多相关文章

  1. 树链剖分入门-Hdu3966 Aragorn's Story

    AC通道:http://acm.hdu.edu.cn/showproblem.php?pid=3966 [题目大意] 一棵树上每个点有权值,每次支持三种操作:给[a,b]路径上的所有节点的权值加上k, ...

  2. hdu3966 Aragorn's Story 树链剖分

    题目传送门 题目大意: 有n个兵营形成一棵树,给出q次操作,每一次操作可以使两个兵营之间的所有兵营的人数增加或者减少同一个数目,每次查询输出某一个兵营的人数. 思路: 树链剖分模板题,讲一下树链剖分过 ...

  3. Aragorn's Story(hdu3966)

    题意:给一棵树,并给定各个点权的值,然后有3种操作: I C1 C2 K: 把C1与C2的路径上的所有点权值加上K D C1 C2 K:把C1与C2的路径上的所有点权值减去K Q C:查询节点编号为C ...

  4. 【hdu3966】Aragorn's Story

    题意:给一棵树,并给定各个点权的值,然后有3种操作:I C1 C2 K: 把C1与C2的路径上的所有点权值加上KD C1 C2 K:把C1与C2的路径上的所有点权值减去KQ C:查询节点编号为C的权值 ...

  5. hdu3966 点权模板-树链部分

    Aragorn's Story Time Limit: 10000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  6. HDU 3966 Aragorn's Story (树链剖分+树状数组)

    Aragorn's Story Time Limit: 10000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  7. HDU 3966 Aragorn's Story 树链剖分+树状数组 或 树链剖分+线段树

    HDU 3966 Aragorn's Story 先把树剖成链,然后用树状数组维护: 讲真,研究了好久,还是没明白 树状数组这样实现"区间更新+单点查询"的原理... 神奇... ...

  8. hdu 3966 Aragorn's Story 树链剖分 按点

    Aragorn's Story Time Limit: 10000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  9. HDU3966(树链剖分)

    题目:Aragorn's Story 题意:给一棵树,并给定各个点权的值,然后有3种操作: I C1 C2 K: 把C1与C2的路径上的所有点权值加上K D C1 C2 K:把C1与C2的路径上的所有 ...

随机推荐

  1. HTML 图片轮播制作工具

    下载地址:http://wowslider.com/download/wowslider-win-setup.zip?utm_source=free_downl_win&utm_medium= ...

  2. Your ApplicationContext is unlikely to start due to a @ComponentScan of the default package

    1.在搭建SpringBoot框架时碰到的问题. ** WARNING ** : Your ApplicationContext is unlikely to start due to a @Comp ...

  3. [UWP 自定义控件]了解模板化控件(5):VisualState

    1. 功能需求 使用TemplatePart实现上篇文章的两个需求(Header为空时隐藏HeaderContentPresenter,鼠标没有放在控件上时HeaderContentPresent半透 ...

  4. Spring Zuul 性能调优,如何提升平均响应时间200% ?

    最近负责公司的 Gateway 项目,我们用 Spring Zuul 来做 HTTP 转发,但是发现请求多的时候,AWS 的健康检查就失败了,但是实际上程序还在跑,在日志上也没有任何东西错误打印出来出 ...

  5. Centos下安装破解Jira7的操作记录

    Jira是一个集项目计划.任务分配.需求管理.错误跟踪于一体的工具,可以作为一个bug管理系统,可以将在测试过程中所发现的bug录入.分配给开发人员.前面介绍了Confluence在Centos下的安 ...

  6. springboot undertow替换tomcat方式

    版权声明: https://blog.csdn.net/weixin_38187317/article/details/81532560说明        undertow,jetty和tomcat可 ...

  7. 读《移山之道——VSTS软件开发指南》

    读<移山之道>这本书差不多用了一个星期的时间,感觉还是收获了一些知识的,以前只是会简单地编个小程序(虽然现在也是这样),但看过这本书之后我对软件开发这个概念的认识度有了从一片模糊到了解大体 ...

  8. 第三个spring冲刺第9天

    今天是第三阶段冲刺的最后第二天了,我们该实现的功能基本已经全部实现了,有填空的,选择题的,还有计时的,目前就是在查BUG,看看有哪些地方有BUG需要修改,以下截图是我们团队所做的功能截图: 首页: 填 ...

  9. Flask-论坛开发-4-知识点补充

    对Flask感兴趣的,可以看下这个视频教程:http://study.163.com/course/courseLearn.htm?courseId=1004091002 1. WTForms 表单使 ...

  10. Installing and removing VNC Connect | Red Hat | VNC Connect

    https://www.realvnc.com/en/connect/docs/redhat-install-remove.html 此软件会和TigerVNC(Server)或者X11VNC Ser ...