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. 1、Zookeeper安装及问题与集群

    1.下载zookeeper.tat.gz压缩包 2.解压 tar –xvf file.tar //解压 tar包 tar -xzvf file.tar.gz //解压tar.gz tar -xjvf ...

  2. ELK-head

    Head从elastic5开始只是支持单独服务器,不能够在通过 elasticsearch/bin/plugin -install mobz/elasticsearch-head 这样简单的方式安装插 ...

  3. LOJ 2736 「JOISC 2016 Day 3」回转寿司 ——堆+分块思路

    题目:https://loj.ac/problem/2736 如果每个询问都是 l = 1 , r = n ,那么每次输出序列的 n 个数与本次操作的数的最大值即可.可以用堆维护. 不同区间的询问,可 ...

  4. openwrt 无线中继

    参考: https://wiki.openwrt.org/doc/recipes/relayclient 该方法可以实现中继AP,而不需要AP(WDS)模式.中继后,相当于该路由所有的LAN口以及AP ...

  5. 使用 Kafka 在生产环境构建大规模机器学习

    智能实时应用为所有行业带来了革命性变化.机器学习及其分支深度学习正蓬勃发展,因为机器学习让计算机能够在无人指引的情况下挖掘深藏的洞见.这种能力正是多种领域所需要的,如非结构化数据分析.图像识别.语音识 ...

  6. 关于libusb-win32开发的经验

    引用:http://blog.sina.com.cn/s/blog_4b4b54da010153zb.html 作为设备开发者, 一般需要让设备与上位机PC通讯, 我们往往考虑采用以下几种接口: rs ...

  7. PI Square中文论坛: PI SDK 开发中级篇| PI Square

    注: 为了更好的利用站内资源营造一个更好的中文开发资源空间,本文为转发修正帖,原作者为OSIsoft技术工程师王曦(Xi Wang),原帖地址:PI SDK 中级篇 来源:https://d.gg36 ...

  8. workerman vmstat服务器状态监控服务

    转载出自 :http://www.workerman.net/workerman-vmstat workerman vmstat服务器状态监控服务 vmstat 命令可以展现服务器的CPU使用率,内存 ...

  9. PREV-9_蓝桥杯_大臣的旅费

    问题描述 很久以前,T王国空前繁荣.为了更好地管理国家,王国修建了大量的快速路,用于连接首都和王国内的各大城市. 为节省经费,T国的大臣们经过思考,制定了一套优秀的修建方案,使得任何一个大城市都能从首 ...

  10. 数据库SQL语言学习--上机练习4(视图)

    上机练习4 一.实验目的 . 熟悉和掌握对数据表中视图的查询操作和 SQL 命令的使用: . 熟悉和掌握对数据表中视图的更新操作和 SQL 命令的使用,并注意视图更新与基本表更新的区别与联系: . 学 ...