54  种草
约翰有 N 个牧场,编号为 1 到 N。它们之间有 N 1 条道路,每条道路连接两个牧场。通过这
些道路,所有牧场都是连通的。
刚开始的时候,所有道路都是光秃秃的,没有青草。约翰会在一些道路上批量种草。每次开始种
草的时候,约翰会选择一个牧场作为起点,一个牧场作为终点,找到从起点到终点的最短路径,在这
条路径上所有的道路上分别种下一棵新的青草。
贝西在监督约翰的工作,她迫不及待地想知道每条道路上已经有多少青草了。约翰的工作总是被
贝西打断,他不胜其烦,所以请你来帮忙回答贝西的问题。约翰的工作和贝西的询问是穿插进行的,
输入数据将会依次出现 M 个事件,以字符 P 开头的事件表示约翰在一条路径上种植了青草,以字符
Q 开头的事件表示贝西在查询一条道路上有多少青草。
输入格式
• 第一行:两个整数 N M, 2 N 105 , 1 M 105
• 第二行到第 N 行:第 i + 1 行有两个整数 Ui Vi,表示第 i 条道路连接的两个牧场编号,
1 Ui,Vi N
• 第 N + 1 行到第 N + Q 行:每行首先由一个大写字母:
如果是 P,随后会有两个整数 A B,表示约翰在从 A 通向 B 的每条道路上都新种了一
棵青草, 1 A,B N
如果是 Q,随后会有两个整数 A B,表示贝西查询一条道路上的青草数量, A B
这条道路的两个端点, 1 A,B N,保证输入数据中存在一条 A B 的道路
输出格式
• 对每个查询请求,输出该条道路上青草的数量,以换行符分隔
样例输入
4 6
1 4
2 4
3 4
P 2 3
P 1 3
Q 3 4
P 1 4
Q 2 4
Q 1 4
样例输出
212

【分析】

  因为是树状数组专题,于是我打了树状数组没有打线段树。

  表示人生第一次树状数组的区间修改和区间查询(我太垃圾..

  其实比线段树可还是短多了,就是维护两个东西的前缀和,一个是delta[i],一个是delta[i]*i,delta[i]表示i~n的共同增量。

  具体看我转的那篇东西:http://www.cnblogs.com/Konjakmoyu/p/5981935.html

  然后就是树剖啦ORZ,好多年没打了居然还能打出来ORZ...

代码如下:

  1. #include<cstdio>
  2. #include<cstdlib>
  3. #include<cstring>
  4. #include<iostream>
  5. #include<algorithm>
  6. #include<queue>
  7. #include<cmath>
  8. using namespace std;
  9. #define Maxn 100010
  10.  
  11. struct node
  12. {
  13. int x,y,next;
  14. }t[Maxn*];int len;
  15. int first[Maxn];
  16.  
  17. void ins(int x,int y)
  18. {
  19. t[++len].x=x;t[len].y=y;
  20. t[len].next=first[x];first[x]=len;
  21. }
  22.  
  23. char s[];
  24.  
  25. int sm[Maxn],son[Maxn],fa[Maxn],dep[Maxn];
  26. void dfs(int x,int f)
  27. {
  28. sm[x]=;son[x]=;fa[x]=f;dep[x]=dep[f]+;
  29. for(int i=first[x];i;i=t[i].next) if(t[i].y!=f)
  30. {
  31. int y=t[i].y;
  32. dfs(y,x);
  33. sm[x]+=sm[y];
  34. if(sm[y]>sm[son[x]]) son[x]=y;
  35. }
  36. }
  37.  
  38. int tp[Maxn],dfn[Maxn],cnt;
  39. void dfs2(int x,int tpp)
  40. {
  41. if(x==) return;
  42. dfn[x]=++cnt;tp[x]=tpp;
  43. dfs2(son[x],tpp);
  44. for(int i=first[x];i;i=t[i].next) if(t[i].y!=fa[x])
  45. {
  46. int y=t[i].y;
  47. if(y==son[x]) continue;
  48. dfs2(y,y);
  49. }
  50. }
  51.  
  52. int c1[Maxn],c2[Maxn];
  53.  
  54. void ffind(int x,int y,int c)
  55. {
  56. for(int i=x;i<=cnt;i+=i&(-i))
  57. c1[i]+=c,c2[i]+=c*x;
  58. y++;
  59. for(int i=y;i<=cnt;i+=i&(-i))
  60. c1[i]+=-c,c2[i]+=(-c)*y;
  61. }
  62.  
  63. int get_ans(int x,int y)
  64. {
  65. int ans=;
  66. for(int i=y;i>=;i-=i&(-i))
  67. ans+=(y+)*c1[i]-c2[i];
  68. x--;
  69. for(int i=x;i>=;i-=i&(-i))
  70. ans-=(x+)*c1[i]-c2[i];
  71. return ans;
  72. }
  73.  
  74. void change(int x,int y)
  75. {
  76. int tt;
  77. while(tp[x]!=tp[y])
  78. {
  79. if(dep[tp[x]]>dep[tp[y]])
  80. {
  81. tt=x,x=y,y=tt;
  82. }
  83. ffind(dfn[tp[y]],dfn[y],);
  84. y=fa[tp[y]];
  85. }
  86. if(x==y) return;
  87. if(dep[x]>dep[y]) tt=x,x=y,y=tt;
  88. ffind(dfn[x]+,dfn[y],);
  89. }
  90.  
  91. int query(int x,int y)
  92. {
  93. int ans=;
  94. int tt;
  95. while(tp[x]!=tp[y])
  96. {
  97. if(dep[tp[x]]>dep[tp[y]])
  98. {
  99. tt=x,x=y,y=tt;
  100. }
  101. ans+=get_ans(dfn[tp[y]],dfn[y]);
  102. y=fa[tp[y]];
  103. }
  104. if(x==y) return ans;
  105. if(dep[x]>dep[y]) tt=x,x=y,y=tt;
  106. ans+=get_ans(dfn[x]+,dfn[y]);
  107. return ans;
  108. }
  109.  
  110. int main()
  111. {
  112. int n,m;
  113. scanf("%d%d",&n,&m);
  114. len=;
  115. memset(first,,sizeof(first));
  116. for(int i=;i<n;i++)
  117. {
  118. int x,y;
  119. scanf("%d%d",&x,&y);
  120. ins(x,y);ins(y,x);
  121. }
  122. sm[]=;dep[]=;
  123. dfs(,);
  124. cnt=;
  125. dfs2(,);
  126.  
  127. memset(c1,,sizeof(c1));
  128. memset(c2,,sizeof(c2));
  129. for(int i=;i<=m;i++)
  130. {
  131. int x,y;
  132. scanf("%s%d%d",s,&x,&y);
  133. if(s[]=='P')
  134. {
  135. change(x,y);
  136. }
  137. else
  138. {
  139. printf("%d\n",query(x,y));
  140. }
  141. }
  142. return ;
  143. }

【SPOJ GRASSPLA】

2016-10-28 09:56:44

【 SPOJ - GRASSPLA】 Grass Planting (树链剖分+树状数组)的更多相关文章

  1. hdu 3966 Aragorn's Story(树链剖分+树状数组/线段树)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3966 题意: 给出一棵树,并给定各个点权的值,然后有3种操作: I C1 C2 K: 把C1与C2的路 ...

  2. Aragorn's Story 树链剖分+线段树 && 树链剖分+树状数组

    Aragorn's Story 来源:http://www.fjutacm.com/Problem.jsp?pid=2710来源:http://acm.hdu.edu.cn/showproblem.p ...

  3. 洛谷 P3384 【模板】树链剖分-树链剖分(点权)(路径节点更新、路径求和、子树节点更新、子树求和)模板-备注结合一下以前写的题目,懒得写很详细的注释

    P3384 [模板]树链剖分 题目描述 如题,已知一棵包含N个结点的树(连通且无环),每个节点上包含一个数值,需要支持以下操作: 操作1: 格式: 1 x y z 表示将树从x到y结点最短路径上所有节 ...

  4. 【LuoguP3038/[USACO11DEC]牧草种植Grass Planting】树链剖分+树状数组【树状数组的区间修改与区间查询】

    模拟题,可以用树链剖分+线段树维护. 但是学了一个厉害的..树状数组的区间修改与区间查询.. 分割线里面的是转载的: ----------------------------------------- ...

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

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

  6. bzoj1146整体二分+树链剖分+树状数组

    其实也没啥好说的 用树状数组可以O(logn)的查询 套一层整体二分就可以做到O(nlngn) 最后用树链剖分让序列上树 #include<cstdio> #include<cstr ...

  7. HDU 5044 (树链剖分+树状数组+点/边改查)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5044 题目大意:修改链上点,修改链上的边.查询所有点,查询所有边. 解题思路: 2014上海网赛的变 ...

  8. BZOJ 1146: [CTSC2008]网络管理Network( 树链剖分 + 树状数组套主席树 )

    树链剖分完就成了一道主席树裸题了, 每次树链剖分找出相应区间然后用BIT+(可持久化)权值线段树就可以完成计数. 但是空间问题很严重....在修改时不必要的就不要新建, 直接修改原来的..详见代码. ...

  9. hdu 3966 Aragorn&#39;s Story(树链剖分+树状数组)

    pid=3966" target="_blank" style="">题目链接:hdu 3966 Aragorn's Story 题目大意:给定 ...

  10. (简单) POJ 3321 Apple Tree,树链剖分+树状数组。

    Description There is an apple tree outside of kaka's house. Every autumn, a lot of apples will grow ...

随机推荐

  1. oracle EBS 基于Host并发程序的开发(转)

    参考此编文章 http://www.doc88.com/p-0972680953307.html http://www.cnblogs.com/benio/archive/2011/06/10/207 ...

  2. hihocoder 第一周 最长回文字串

    题目1 : 最长回文子串 时间限制:1000ms 单点时限:1000ms 内存限制:64MB 描述 小Hi和小Ho是一对好朋友,出生在信息化社会的他们对编程产生了莫大的兴趣,他们约定好互相帮助,在编程 ...

  3. 对bigDecimal的一些探索

    一般直接用简单的double等来做浮点计算可能会因为计算机的浮点运算机制出现一点问题,不符合生活中的计算常识,于是java就给我们包装了大数据类,bigdecimal用于处理浮点数据类.当然也有处理整 ...

  4. Sql2008的行列转换之行转列

    今天在工作的时候遇到了行列转换的问题,记得去年有一段时间经常写,但是许久不用已经记不太得了.好记性不如烂笔头,忙完之后赶紧记录一下. 关键字:PIVOT(行转列),UNPIVOT(列转行) 先说说 P ...

  5. 用Android-X86和VirtualBox打造高性能Android开发环境

    不知道有多少Android开发着对Android虚拟机的那悲剧的性能有意见,反正我的看法是:那速度实在是太坑爹了! 为什么Android虚拟机比iOS和WP7的虚拟机要慢很多呢?原因如下: 1. An ...

  6. Excel表数据导入数据库表中

    ***Excel表数据导入到数据库表中 通过数据库表的模板做成‘Excel’表的数据导入到数据库相应的表中(注意:主表 和 从表的关系,要先导‘主表’在导入从表) 过程:通过数据库的导入工具—先导入为 ...

  7. C# Flash 图片上传案例(结合网上腾讯头像上传Flash插件)

    之前遇到过很多次要上传类似头像图片这种功能需求,这次是要求弄一个flash插件上传图片 感谢主,一个偶然机会在网上找到了一个很好的腾讯头像修改的flash插件:插件下载 这个功能采用Ajax访问支持, ...

  8. jquery杂记之checkbox控制select置灰

    jquery: $(function(){ $("#avg_day_live").bind("click",function(){   //点击 if($(&q ...

  9. Ext.Net学习笔记10:Ext.Net ComboBox用法

    ComboBox是最常用的控件之一,它与HTML中的Select控件很像,但可以进行多选.自定义显示格式.分页等. ComboBox用法 <ext:ComboBox runat="se ...

  10. 响应者链 hittest:withEvent: 方法的使用

    关于响应者链部分的基础内容 参考http://www.cnblogs.com/wendingding/p/3795171.html 这里我要说明的是 关于- (UIView *)hitTest:(CG ...