1. /*
  2. 考虑将所求的值拆分
  3. 记每个点到根的路径长度为dis_i, 那么我们要求的就是\sum_{i = l} ^ r dis_i + dis[u] * (r - l + 1)
  4. - 2\sum_{i = l} ^ r dis_{LCA(i, u)}
  5. 前两个前缀和处理
  6. 对于第三个可以转换成一个经典问题, 就是对于每个点到根的路径 + 1, 那么第三个东西就是这个点到根的贡献和了
  7. */
  8. #include<cstdio>
  9. #include<algorithm>
  10. #include<cstring>
  11. #include<queue>
  12. #include<iostream>
  13. #define ll long long
  14. #define mmp make_pair
  15. #define M 200010
  16. using namespace std;
  17. int read()
  18. {
  19. int nm = 0, f = 1;
  20. char c = getchar();
  21. for(; !isdigit(c); c = getchar()) if(c == '-') f = -1;
  22. for(; isdigit(c); c = getchar()) nm = nm * 10 + c - '0';
  23. return nm * f;
  24. }
  25. int n, q, A, sz[M], son[M], fa[M], top[M], dfn[M], dft, ver[M], cnt;
  26. ll dis[M], ans, sum[M], w[M];
  27. pair<int, int> sta[M];
  28. vector<pair<int, int> > to[M];
  29. int lc[10001000], rc[10001000], v[10001000], rt[M];
  30. ll t[10001000];
  31. void dfs(int now, int f)
  32. {
  33. sz[now] = 1;
  34. fa[now] = f;
  35. for(int i = 0; i < to[now].size(); i++)
  36. {
  37. int vj = to[now][i].first, v = to[now][i].second;
  38. if(vj == f) continue;
  39. dis[vj] = dis[now] + v;
  40. ver[vj] = v;
  41. dfs(vj, now);
  42. if(sz[vj] > sz[son[now]]) son[now] = vj;
  43. sz[now] += sz[vj];
  44. }
  45. }
  46. void dfs(int now)
  47. {
  48. dfn[now] = ++dft;
  49. w[dfn[now]] = ver[now];
  50. if(son[now])
  51. {
  52. top[son[now]] = top[now];
  53. dfs(son[now]);
  54. }
  55. for(int i = 0; i < to[now].size(); i++)
  56. {
  57. int vj = to[now][i].first;
  58. if(vj == fa[now] || vj == son[now]) continue;
  59. top[vj] = vj;
  60. dfs(vj);
  61. }
  62. }
  63. void modify(int last, int &now, int l, int r, int ln, int rn)
  64. {
  65. now = ++cnt;
  66. lc[now] = lc[last], rc[now] = rc[last], t[now] = t[last], v[now] = v[last];
  67. if(l == ln && r == rn)
  68. {
  69. v[now]++;
  70. return;
  71. }
  72. t[now] += w[rn] - w[ln - 1];
  73. int mid = (l + r) >> 1;
  74. if(ln > mid) modify(rc[last], rc[now], mid + 1, r, ln, rn);
  75. else if(rn <= mid) modify(lc[last], lc[now], l, mid, ln, rn);
  76. else modify(lc[last], lc[now], l, mid, ln, mid), modify(rc[last], rc[now], mid + 1, r, mid + 1, rn);
  77. }
  78. ll query(int now, int l, int r, int ln, int rn)
  79. {
  80. ll ans = 1ll * (w[rn] - w[ln - 1]) * v[now];
  81. if(l == ln && r <= rn) return ans + t[now];
  82. int mid = (l + r) >> 1;
  83. if(rn <= mid) return ans + query(lc[now], l, mid, ln, rn);
  84. else if(ln > mid) return ans + query(rc[now], mid + 1, r, ln, rn);
  85. else return ans + query(lc[now], l, mid, ln, mid) + query(rc[now], mid + 1, r, mid + 1, rn);
  86. }
  87. void Modify(int &now, int x)
  88. {
  89. for(; top[x] != 1; x = fa[top[x]]) modify(now, now, 1, n, dfn[top[x]], dfn[x]);
  90. modify(now, now, 1, n, dfn[1], dfn[x]);
  91. }
  92. ll Query(int now, int x)
  93. {
  94. ll ans = 0;
  95. for(; top[x] != 1; x = fa[top[x]]) ans += query(now, 1, n, dfn[top[x]], dfn[x]);
  96. ans += query(now, 1, n, dfn[1], dfn[x]);
  97. return ans;
  98. }
  99. int main()
  100. {
  101. n = read(), q = read(), A = read();
  102. for(int i = 1; i <= n; i++) sta[i] = mmp(read(), i);
  103. sort(sta + 1, sta + n + 1);
  104. for(int i = 1; i < n; i++)
  105. {
  106. int vi = read(), vj = read(), v = read();
  107. to[vi].push_back(mmp(vj, v));
  108. to[vj].push_back(mmp(vi, v));
  109. }
  110. dfs(1, 0);
  111. top[1] = 1;
  112. dfs(1);
  113. for(int i = 1; i <= n; i++) sum[i] = sum[i - 1] + dis[sta[i].second], w[i] += w[i - 1];
  114. for(int i = 1; i <= n; i++) rt[i] = rt[i - 1], Modify(rt[i], sta[i].second);
  115. while(q--)
  116. {
  117. int u = read(), l = read(), r = read();
  118. l = (ans + l) % A, r = (ans + r) % A;
  119. if(r < l) swap(l, r);
  120. ans = 0;
  121. l = lower_bound(sta + 1, sta + n + 1, mmp(l, 0)) - sta,
  122. r = lower_bound(sta + 1, sta + n + 1, mmp(r, 0x3e3e3e3e)) - sta - 1;
  123. ans += Query(rt[l - 1], u);
  124. ans -= Query(rt[r], u);
  125. ans *= 2;
  126. ans += 1ll * (r - l + 1) * dis[u];
  127. ans += sum[r] - sum[l - 1];
  128. cout << ans << "\n";
  129. }
  130. return 0;
  131. }

「HNOI2015」开店(树链剖分, 主席树)的更多相关文章

  1. dfs序+主席树 或者 树链剖分+主席树(没写) 或者 线段树套线段树 或者 线段树套splay 或者 线段树套树状数组 bzoj 4448

    4448: [Scoi2015]情报传递 Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 588  Solved: 308[Submit][Status ...

  2. BZOJ4012 HNOI2015开店(树链剖分+主席树)

    考虑这样一个问题:一棵树初始全是白点,有两种操作:把一个点染黑:询问某点到所有黑点的距离之和. 注意到树上两点x和y的距离为depth[x]+depth[y]-depth[lca(x,y)]*2.要求 ...

  3. Codechef FIBTREE 树链剖分 主席树 LCA 二次剩余 快速幂

    原文链接https://www.cnblogs.com/zhouzhendong/p/CC-FIBTREE.html 题目传送门 - CC-FIBTREE 题意 给定一个有 $n$ 个节点,初始点权都 ...

  4. BZOJ1146 [CTSC2008]网络管理Network 树链剖分 主席树 树状数组

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1146 题意概括 在一棵树上,每一个点一个权值. 有两种操作: 1.单点修改 2.询问两点之间的树链 ...

  5. bzoj 4448 [Scoi2015]情报传递 (树链剖分+主席树)

    题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=4448 题面: Description 奈特公司是一个巨大的情报公司,它有着庞大的情报网络 ...

  6. BZOJ 4448: [Scoi2015]情报传递 树链剖分 主席树

    4448: [Scoi2015]情报传递 题目连接: http://www.lydsy.com/JudgeOnline/problem.php?id=4448 Description 奈特公司是一个巨 ...

  7. [GDOI2016][树链剖分+主席树]疯狂动物城

    题面 Description Nick 是只在动物城以坑蒙拐骗为生的狐狸,儿时受到偏见的伤害,放弃了自己的理想.他被兔子 Judy 设下圈套,被迫与她合作查案,而卷入意想不到的阴谋,历尽艰险后成为搭档 ...

  8. HDU 5111 Alexandra and Two Trees 树链剖分 + 主席树

    题意: 给出两棵树,每棵树的节点都有一个权值. 同一棵树上的节点的权值互不相同,不同树上节点的权值可以相同. 要求回答如下询问: \(u_1 \, v_1 \, u_2 \, v_2\):询问第一棵树 ...

  9. 5.15 牛客挑战赛40 E 小V和gcd树 树链剖分 主席树 树状数组 根号分治

    LINK:小V和gcd树 时限是8s 所以当时好多nq的暴力都能跑过. 考虑每次询问暴力 跳父亲 这样是nq的 4e8左右 随便过. 不过每次跳到某个点的时候需要得到边权 如果直接暴力gcd的话 nq ...

  10. BZOJ3531 SDOI2014 旅行 - 树链剖分,主席树

    题意:给定一棵树,树上每个点有权值和类型.支持:修改某个点的类型:修改某个点的权值:询问某条链上某个类型的点的和/最大值.点数/类型数/询问数<=100000. 分析: 树链剖分,对每个类型的点 ...

随机推荐

  1. hdu 1693 Eat the Trees——插头DP

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=1693 第一道插头 DP ! 直接用二进制数表示状态即可. #include<cstdio> # ...

  2. HTTP 状态码的完整列表

    一.1xx(临时响应) 表示临时响应并需要请求者继续执行操作的状态码.SC_CONTINUE = 100; 100(继续)请求者应当继续提出请求.服务器返回此代码表示已收到请求的第一部分,正在等待其余 ...

  3. C# 结构和类

    不同点: 1.结构是值类型,而类是引用类型:2.结构不支持继承,而类支持继承:3.结构不能定义构造函数,编译器会定义. 适用场合: 结构:分配内存快,作用域结束即被删除,不需要垃圾回收,适用于小型数据 ...

  4. MySQL体系架构

    MySQL体系架构 学习一门数据库系统首先得了解它的架构,明白它的架构原理对于后期的分析问题和性能调优都有很大的帮助,接下来就通过分析架构图来认识它. 数据库:物理操作系统文件或者其它文件的集合,在m ...

  5. angularjs 外部调用controller中的方法

    angular.element(document.querySelector('[ng-controller=mainCtrl]')).scope().viewGo('tab.VIPPay_Succe ...

  6. PHP-不同Str 拼接方法性能对比

    问题 在PHP中,有多种字符串拼接的方式可供选择,共有: 1 . , .= , sprintf, vprintf, join, implode 那么,那种才是最快的,或者那种才是最适合业务使用的,需要 ...

  7. 用DDE控制Word

    DDE(Dynamic Data Exchange),称为动态数据交换.用于进程间的通讯,看看他如何来和Word交互. 在System页签下有TDdeClientConv组件,拖一个放到界面上,然后我 ...

  8. Django-models-迁移错误

    错误表现:数据表二次迁移时:django.db.utils.InternalError: (1138, 'Invalid use of NULL value') 错误原因:是因为二次修改了null值属 ...

  9. draftsight的热补丁

    http://www.piaodown.com/soft/134200.htm DraftSight HotFix 2017R3热修复补丁下载.DraftSight,一个非常好用的2D制图软件,由开发 ...

  10. LeetCode——13. Roman to Integer

    一.题目链接:https://leetcode.com/problems/roman-to-integer/ 二.题目大意: 给定一个罗马数字,返回它的整数形式. 三.题解: 这道题与12题恰好相反, ...