题意:紫妹和幽香是17岁的少女,喜欢可爱的东西。

给定一棵树,有点权,边权。每次求所有权值在[l, r]范围内的点到点x的距离和。强制在线。

解:动态点分治怎么搞啊......

一开始想的是权值的限制直接外层权值线段树就行了,关键是怎么批量求距离。

jxl想的是树上莫队的方法,括号序列。然后发现当x和y在不同子树的时候,x -> lca的距离是负的。

然后考虑lca。距离是d[x] + d[y] - 2d[lca],前面两个都好求,主要是第三项。

稍稍思考一下,lca只可能是x到根路径上的点。每个点作为lca的次数就是siz - siz[son]

所以可以转为计算每条边的贡献。每条边的贡献就是它下面的子树大小。这样就可以做了。

具体来说,d[x] * cnt和∑d[y]可以用两个前缀和数组求出。以离散化后的权值为下标。

然后建一个以权值为版本的主席树,线段树上维护的是DFS序的该点的父边的计算次数。

可以发现,按照权值我们每插入一个点,就要对它到根的路径进行修改。查询的时候也是查询x到根的路径。所以我们必须写树剖了>_<

主席树区间加区间查,使用标记永久化。

然后发现我之前以为的标记永久化都是假的......

具体来说,给一个区间加的时候,它途中经过的区间都要加上相应的值,而标记只打在最后的区间。

查询的时候,沿途记录标记数量。到终点的时候,用终点的sum + 区间Val * 标记数量即可。

如果修改在查询上面,那么你会把标记记录下来,最后在终点区间加上。

如果修改在下,那么你终点区间的sum已经加了那一次修改的影响。

然后这道毒瘤SB题就这样A了...时间复杂度nlog2n。

  1. #include <cstdio>
  2. #include <algorithm>
  3.  
  4. typedef long long LL;
  5. const int N = , lm = 1e9, M = ;
  6.  
  7. struct Edge {
  8. int nex, v, len;
  9. }edge[N << ]; int tp;
  10.  
  11. struct Node {
  12. int val, p;
  13. inline bool operator <(const Node &w) const {
  14. return val < w.val;
  15. }
  16. }node[N];
  17.  
  18. int e[N], n, top[N], son[N], fa[N], pos[N], num, siz[N], X[N], deep[N], Sum[N], id[N], val2[N], tot, rt[N], val[N];
  19. LL Val[M], d[N], exVal[N];
  20. int ls[M], rs[M], exsum[N], tag[M];
  21.  
  22. inline void add(int x, int y, int z) {
  23. tp++;
  24. edge[tp].v = y;
  25. edge[tp].len = z;
  26. edge[tp].nex = e[x];
  27. e[x] = tp;
  28. return;
  29. }
  30.  
  31. void DFS_1(int x, int f) { // siz fa d son
  32. fa[x] = f;
  33. siz[x] = ;
  34. deep[x] = deep[f] + ;
  35. for(int i = e[x]; i; i = edge[i].nex) {
  36. int y = edge[i].v;
  37. if(y == f) {
  38. continue;
  39. }
  40. d[y] = d[x] + edge[i].len;
  41. val2[y] = edge[i].len;
  42. DFS_1(y, x);
  43. siz[x] += siz[y];
  44. if(siz[y] > siz[son[x]]) {
  45. son[x] = y;
  46. }
  47. }
  48. return;
  49. }
  50.  
  51. void DFS_2(int x, int f) { // pos top
  52. top[x] = f;
  53. pos[x] = ++num;
  54. id[num] = x;
  55. if(son[x]) {
  56. DFS_2(son[x], f);
  57. }
  58. for(int i = e[x]; i; i = edge[i].nex) {
  59. int y = edge[i].v;
  60. if(y == fa[x] || y == son[x]) {
  61. continue;
  62. }
  63. DFS_2(y, y);
  64. }
  65. return;
  66. }
  67.  
  68. void Add(int x, int &y, int L, int R, int l, int r) {
  69. if(!y || y == x) {
  70. y = ++tot;
  71. Val[y] = Val[x];
  72. tag[y] = tag[x];
  73. ls[y] = ls[x];
  74. rs[y] = rs[x];
  75. //printf("new %d [%d %d] val = %lld \n", y, l, r, Val[y]);
  76. }
  77. Val[y] += Sum[std::min(R, r)] - Sum[std::max(L, l) - ];
  78. //printf("val %d = %lld += (%d %d) %d \n", y, Val[y], std::min(R, r), std::max(L, l) - 1, Sum[std::min(R, r)] - Sum[std::max(L, l) - 1]);
  79. if(L <= l && r <= R) {
  80. tag[y]++;
  81. return;
  82. }
  83. int mid = (l + r) >> ;
  84. if(L <= mid) {
  85. Add(ls[x], ls[y], L, R, l, mid);
  86. }
  87. if(mid < R) {
  88. Add(rs[x], rs[y], L, R, mid + , r);
  89. }
  90. return;
  91. }
  92.  
  93. inline void insert(int x, int id) {
  94. while(x) {
  95. //printf("id = %d \n", id);
  96. Add(rt[id - ], rt[id], pos[top[x]], pos[top[x]] + (deep[x] - deep[top[x]]), , n);
  97. x = fa[top[x]];
  98. }
  99. return;
  100. }
  101.  
  102. LL Ask(int x, int y, int L, int R, int l, int r, int tagx, int tagy) {
  103. if(L <= l && r <= R) {
  104. return Val[y] - Val[x] + 1ll * (tagy - tagx) * (Sum[r] - Sum[l - ]);
  105. }
  106. tagx += tag[x];
  107. tagy += tag[y];
  108. int mid = (l + r) >> ;
  109. LL ans = ;
  110. if(L <= mid) {
  111. ans += Ask(ls[x], ls[y], L, R, l, mid, tagx, tagy);
  112. }
  113. if(mid < R) {
  114. ans += Ask(rs[x], rs[y], L, R, mid + , r, tagx, tagy);
  115. }
  116. return ans;
  117. }
  118.  
  119. LL ask(int l, int r, int x) {
  120. LL ans = ;
  121. while(x) {
  122. LL t = Ask(rt[l - ], rt[r], pos[top[x]], pos[top[x]] + (deep[x] - deep[top[x]]), , n, , );
  123. ans += t;
  124. x = fa[top[x]];
  125. }
  126. return ans;
  127. }
  128.  
  129. int main() {
  130.  
  131. //freopen("in.in", "r", stdin);
  132. //freopen("my.out", "w", stdout);
  133.  
  134. int q, A;
  135. scanf("%d%d%d", &n, &q, &A);
  136. for(int i = ; i <= n; i++) {
  137. scanf("%d", &val[i]);
  138. val[i]++;
  139. node[i].p = i;
  140. X[i] = val[i];
  141. }
  142. for(int i = , x, y, z; i < n; i++) {
  143. scanf("%d%d%d", &x, &y, &z);
  144. add(x, y, z);
  145. add(y, x, z);
  146. }
  147. // prework
  148.  
  149. DFS_1(, );
  150. DFS_2(, );
  151. std::sort(X + , X + n + );
  152. int temp = std::unique(X + , X + n + ) - X - ;
  153. for(int i = ; i <= n; i++) {
  154. val[i] = std::lower_bound(X + , X + temp + , val[i]) - X;
  155. node[i].val = val[i];
  156. exsum[val[i]]++;
  157. exVal[val[i]] += d[i];
  158. }
  159. for(int i = ; i <= temp; i++) {
  160. exsum[i] += exsum[i - ];
  161. exVal[i] += exVal[i - ];
  162. }
  163. for(int i = ; i <= n; i++) {
  164. Sum[i] = Sum[i - ] + val2[id[i]];
  165. }
  166. std::sort(node + , node + n + );
  167. for(int i = ; i <= n; i++) {
  168. insert(node[i].p, node[i].val);
  169. }
  170.  
  171. LL lastans = ;
  172. for(int i = , x, y, z; i <= q; i++) {
  173. scanf("%d%d%d", &x, &y, &z);
  174. int l = (y + lastans) % A + ;
  175. int r = (z + lastans) % A + ;
  176. if(l > r) {
  177. std::swap(l, r);
  178. }
  179. l = std::lower_bound(X + , X + temp + , l) - X;
  180. r = std::upper_bound(X + , X + temp + , r) - X - ;
  181. if(l > r) {
  182. lastans = ;
  183. printf("%lld\n", lastans);
  184. }
  185. else {
  186. LL t = ask(l, r, x);
  187. lastans = 1ll * d[x] * (exsum[r] - exsum[l - ]) + (exVal[r] - exVal[l - ]);
  188. lastans -= t * ;
  189. printf("%lld\n", lastans);
  190. }
  191. }
  192.  
  193. return ;
  194. }

AC代码

洛谷P3241 开店的更多相关文章

  1. 洛谷 P3241 [HNOI2015]开店 解题报告

    P3241 [HNOI2015]开店 题目描述 风见幽香有一个好朋友叫八云紫,她们经常一起看星星看月亮从诗词歌赋谈到人生哲学.最近她们灵机一动,打算在幻想乡开一家小店来做生意赚点钱. 这样的想法当然非 ...

  2. 洛谷1640 bzoj1854游戏 匈牙利就是又短又快

    bzoj炸了,靠离线版题目做了两道(过过样例什么的还是轻松的)但是交不了,正巧洛谷有个"大牛分站",就转回洛谷做题了 水题先行,一道傻逼匈牙利 其实本来的思路是搜索然后发现写出来类 ...

  3. 洛谷P1352 codevs1380 没有上司的舞会——S.B.S.

    没有上司的舞会  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond       题目描述 Description Ural大学有N个职员,编号为1~N.他们有 ...

  4. 洛谷P1108 低价购买[DP | LIS方案数]

    题目描述 “低价购买”这条建议是在奶牛股票市场取得成功的一半规则.要想被认为是伟大的投资者,你必须遵循以下的问题建议:“低价购买:再低价购买”.每次你购买一支股票,你必须用低于你上次购买它的价格购买它 ...

  5. 洛谷 P2701 [USACO5.3]巨大的牛棚Big Barn Label:二维数组前缀和 你够了 这次我用DP

    题目背景 (USACO 5.3.4) 题目描述 农夫约翰想要在他的正方形农场上建造一座正方形大牛棚.他讨厌在他的农场中砍树,想找一个能够让他在空旷无树的地方修建牛棚的地方.我们假定,他的农场划分成 N ...

  6. 洛谷P1710 地铁涨价

    P1710 地铁涨价 51通过 339提交 题目提供者洛谷OnlineJudge 标签O2优化云端评测2 难度提高+/省选- 提交  讨论  题解 最新讨论 求教:为什么只有40分 数组大小一定要开够 ...

  7. 洛谷P1371 NOI元丹

    P1371 NOI元丹 71通过 394提交 题目提供者洛谷OnlineJudge 标签云端评测 难度普及/提高- 提交  讨论  题解 最新讨论 我觉得不需要讨论O long long 不够 没有取 ...

  8. 洛谷P1538迎春舞会之数字舞蹈

    题目背景 HNSDFZ的同学们为了庆祝春节,准备排练一场舞会. 题目描述 在越来越讲究合作的时代,人们注意的更多的不是个人物的舞姿,而是集体的排列. 为了配合每年的倒计时,同学们决定排出——“数字舞蹈 ...

  9. 洛谷八月月赛Round1凄惨记

    个人背景: 上午9:30放学,然后因为学校举办读书工程跟同学去书城选书,中午回来开始打比赛,下午又回老家,中间抽出一点时间调代码,回家已经8:50了 也许是7月月赛时“连蒙带骗”AK的太幸运然而因同学 ...

随机推荐

  1. 《网路对抗》Exp8 WEB基础实践

    20155336<网路对抗>Exp8 WEB基础实践 一.基础问题回答 1.什么是表单 表单是一个包含表单元素的区域,表单元素是允许用户在表单中(比如:文本域.下拉列表.单选框.复选框等等 ...

  2. 11、可扩展MySQL+12、高可用

    11.1.扩展MySQL 静态分片:根据key取hash,然后取模: 动态分片:用一个表来维护key与分片id的关系: 11.2.负载均衡 12. 12.2导致宕机得原因: 35%环境+35%性能+2 ...

  3. Linux 设置core dump

    Linux 设置core dump

  4. CodeForces-1155D Beautiful Array

    Description You are given an array \(a\) consisting of \(n\) integers. Beauty of array is the maximu ...

  5. Centos7下python3安装ipython

    一.通过压缩包安装ipython 1.下载ipython安装包 [root@localhost ~]# wget https://pypi.python.org/packages/79/63/b671 ...

  6. 移动端页面滑动时候警告:Unable to preventDefault inside passive event listener due to target being treated as passive.

    移动端项目中,在滚动的时候,会报出以下提示: [Intervention] Unable to preventDefault inside passive event listener due to ...

  7. 生成本地测试用https证书,支持通配符和多域名,初学OpenSSL

    18-01-26在v2ex上看到一妹纸发的<身为一个 21 岁的年轻程序员,我已经腰突了(躺>,哈哈,感同身受,想到这几天我左腿麻木持续了好几天,前几天屁股疼的只要坐下就站不起来,不过站着 ...

  8. CSS技巧收集——巧用滤镜

    最近暴雪一款叫<守望先锋>的游戏火到不行,身边很多人都深受其毒害,虽然博主自己没有买(穷),但是耳濡目染也了解了个大概. 由于之前大致学习了一下 css 滤镜的各种用法,所以心血来潮结合二 ...

  9. selenium+python自动化----xlrd,xlswriter

    1.准备: 使用之前需要先按照:打开cmd,输入pip install xlrd(xlswriter),点击enter; 2.基本使用: xlrd: #打开els文件,参数是文件路径: table = ...

  10. 转 Git 常用命令大全

    一. Git 常用命令速查 git branch 查看本地所有分支 git status 查看当前状态  git commit 提交  git branch -a 查看所有的分支 git branch ...