/*
写完开店再写这个题目顿时神清气爽, 腰也不疼了, 眼也不花了首先考虑将询问拆开, 就是查询一些到根的链和点k的关系根据我们开店的结论, 一个点集到一个定点的距离和可以分三部分算
那么就很简单了吧QAQ, 在树上可持久化弄一下 */#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#include<iostream>
#define ll long long
#define mmp make_pair
#define M 200010
using namespace std;
int read()
{int nm = 0, f = 1;char c = getchar();for(; !isdigit(c); c = getchar()) if(c == '-') f = -1;for(; isdigit(c); c = getchar()) nm = nm * 10 + c - '0';return nm * f;
}int type, n, q, sz[M], son[M], fa[M], top[M], dfn[M], ver[M], dft, cnt, p[M], deep[M];
ll dis[M], sum[M], w[M], ans;
vector<pair<int,int> > to[M];
int lc[20000100], rc[20000100], v[20000100], rt[M];
ll t[20000100];void dfs(int now, int f)
{deep[now] = deep[f] + 1;sz[now] = 1;fa[now] = f;for(int i = 0; i < to[now].size(); i++){int vj = to[now][i].first, v = to[now][i].second;if(vj == f) continue;dis[vj] = dis[now] + v;ver[vj] = v;
//      deep[vj] = deep[now] + 1;dfs(vj, now);if(sz[vj] > sz[son[now]]) son[now] = vj;sz[now] += sz[vj];}
}void dfs(int now)
{dfn[now] = ++cnt;w[cnt] = ver[now];if(son[now]){top[son[now]] = top[now];dfs(son[now]);}for(int i = 0; i < to[now].size(); i++){int vj = to[now][i].first;if(vj == fa[now] || vj == son[now]) continue;top[vj] = vj;dfs(vj);}
}void modify(int last, int &now, int l, int r, int ln, int rn)
{now = ++cnt;lc[now] = lc[last], rc[now] = rc[last], t[now] = t[last], v[now] = v[last];if(l == ln && r == rn){v[now]++;return;}t[now] += w[rn] - w[ln - 1];int mid = (l + r) >> 1;if(ln > mid) modify(rc[last], rc[now], mid + 1, r, ln, rn);else if(rn <= mid) modify(lc[last], lc[now], l, mid, ln, rn);else modify(lc[last], lc[now], l, mid, ln, mid), modify(rc[last], rc[now], mid + 1, r, mid + 1, rn);
}ll query(int now, int l, int r, int ln, int rn)
{ll ans = 1ll * (w[rn] - w[ln - 1]) * v[now];if(l == ln && r <= rn) return ans + t[now];int mid = (l + r) >> 1;if(rn <= mid) return ans + query(lc[now], l, mid, ln, rn);else if(ln > mid) return ans + query(rc[now], mid + 1, r, ln, rn);else return ans + query(lc[now], l, mid, ln, mid) + query(rc[now], mid + 1, r, mid + 1, rn);
}void Modify(int &now, int x)
{for(; top[x] != 1; x = fa[top[x]]) modify(now, now, 1, n, dfn[top[x]], dfn[x]);modify(now, now, 1, n, dfn[1], dfn[x]);
}void work(int now)
{rt[now] = rt[fa[now]];Modify(rt[now], p[now]);sum[now] = dis[p[now]] + sum[fa[now]];for(int i = 0; i < to[now].size(); i ++){int vj = to[now][i].first;if(vj == fa[now]) continue;work(vj);}
}ll Query(int x, int k)
{if(k == 0) return 0;
//  cout << k << " ";ll ans = sum[x];ans += dis[k] * deep[x];for(; top[k] != 1; k = fa[top[k]]) ans -= 2ll * query(rt[x], 1, n, dfn[top[k]], dfn[k]);ans -= 2ll *query(rt[x], 1, n, dfn[1], dfn[k]);
//  cout << x  << " " << ans << "!!!!!!!\n";return ans;
}int LCA(int a, int b)
{while(top[a] != top[b]){if(deep[top[a]] < deep[top[b]]) swap(a, b);a = fa[top[a]];}if(deep[a] > deep[b]) swap(a, b);return a;
}int main()
{type = read(); n = read(), q = read();for(int i = 1; i < n; i++){int vi = read(), vj = read(), v = read();to[vi].push_back(mmp(vj, v));to[vj].push_back(mmp(vi, v));}for(int i = 1; i <= n; i++) p[i] = read();dfs(1, 0);top[1] = 1;dfs(1);for(int i = 1; i <= n; i++) w[i] += w[i - 1];work(1);while(q--){ll vi = read() ^ ans, vj = read() ^ ans, k = read() ^ ans;int l = LCA(vi, vj);ans = Query(vi, k) + Query(vj, k) - Query(l, k) - Query(fa[l], k);cout << ans << "\n";ans *= type;}return 0;
}

转载于:https://www.cnblogs.com/luoyibujue/p/10620465.html

「2017 山东一轮集训 Day5」距离相关推荐

  1. #6073. 「2017 山东一轮集训 Day5」距离(树链剖分 + 永久标记主席树)

    #6073. 「2017 山东一轮集训 Day5」距离 给定一颗有nnn个节点带边权的树,以及一个排列ppp,path(u,v)path(u, v)path(u,v)为u,vu, vu,v路径上的点集 ...

  2. LOJ#6072. 「2017 山东一轮集训 Day5」苹果树 解题报告

    LOJ#6072. 「2017 山东一轮集训 Day5」苹果树 解题报告 好苹果会组成连通块,整棵树的权值为 ∑ i = 1 n c i [ c i ≥ 0 ] [ s i z n u m ( c i ...

  3. Loj #6077. 「2017 山东一轮集训 Day7」逆序对

    Loj #6077. 「2017 山东一轮集训 Day7」逆序对 Solution 令fi,jf_{i,j}fi,j​表示前iii个数产生jjj个逆序对的方案数,每次考虑把i+1i+1i+1加入,有i ...

  4. 容斥问卷调查反馈——Co-prime,Character Encoding,Tree and Constraints,「2017 山东一轮集训 Day7」逆序对

    文章目录 Co-prime source solution code Character Encoding source solution code Tree and Constraints sour ...

  5. LOJ#6074. 「2017 山东一轮集训 Day6」子序列

    LOJ#6074. 「2017 山东一轮集训 Day6」子序列 先考虑全局询问怎么做,设 f ( i , c ) f(i,c) f(i,c) 表示在 S 1 ⋯ i S_{1\cdots i} S1⋯ ...

  6. LOJ#6103. 「2017 山东二轮集训 Day2」第一题 解题报告

    LOJ#6103. 「2017 山东二轮集训 Day2」第一题 解题报告 前置知识:闭区间上的连续函数的零点存在性定理: 我们定义这样的函数: 定义域为 [ l , r ] ∩ Z [l,r]\cap ...

  7. LOJ6079「2017 山东一轮集训 Day7」养猫

    养ImmortalCO k可重区间问题 的增强版:有上下界! 直接都选择s[i],然后再把一些调整到e[i] 考虑通过最大流的"最大",使得至少每k个有me个e, 通过最大流的&q ...

  8. [LOJ#6068]. 「2017 山东一轮集训 Day4」棋盘[费用流]

    题意 题目链接 分析 考虑每个棋子对对应的横向纵向的极大区间的影响:记之前这个区间中的点数为 \(x\) ,那么此次多配对的数量即 \(x\) . 考虑费用流,\(S\rightarrow 横向区间 ...

  9. 「2017 山东一轮集训 Day2」Pair (霍尔定理+线段树)

    题目描述 给出一个长度为  的数列  和一个长度为  的数列 ,求  有多少个长度为  的连续子数列能与  匹配. 两个数列可以匹配,当且仅当存在一种方案,使两个数列中的数可以两两配对,两个数可以配对 ...

最新文章

  1. LeetCode Algorithm 204. 计数质数
  2. unity应用开发实战案例_Unity游戏案例开发大全 (吴亚峰等著) 完整pdf高清版[31MB]...
  3. 单元测试怎么测试线程_单元测试线程代码的5个技巧
  4. Viewport的使用《转》
  5. 图解DotNet框架之三:System.IO
  6. linux网络编程学习笔记之四 -----多-threaded服务器
  7. Python---PDF转JPG图片
  8. Phase2 Day16 数据库SQL
  9. 松本行弘为什么开发Ruby
  10. 1.1计算机解决问题的过程教案,1.1 计算机解决问题的过程
  11. Photoshop制作印章效果
  12. Python之OpenCV 007 《走近混沌》分形艺术Fractal之美
  13. 看完这篇,轻松解决FastReport合并单元格!
  14. USB转TTL、USB转RS232的实现
  15. testerhome学习笔记1_互联网测试技术
  16. lua table是否为空的判断
  17. Mac M1 搭建虚拟机节点集群过程及软件分享
  18. kepp-alive的作用?keep-alive的属性?路由元信息?白名单黑名单?keep-alive的钩子函数
  19. 计算机毕业设计ssm基于SSM的美妆分享网站vf952系统+程序+源码+lw+远程部署
  20. 2022电工(初级)考试题库模拟考试平台操作

热门文章

  1. BZOJ 1046: [HAOI2007]上升序列(LIS)
  2. Android中Alertdialog对话框点击消失?
  3. C语言中控制printf的打印颜色实例及vt100的控制符
  4. 分布式服务框架 Zookeeper — 管理分布式环境中的数据
  5. 患者信息可视化及关联规则可视化
  6. 钉钉内部视频遭曝光:疯子无招“逼疯”产品经理
  7. 吐血整理所有常用端口,遇到端口问题一查就懂!
  8. Http协议中的Content-Length属性
  9. Vertica集群扩容实验过程记录
  10. 每瓶汽水一元,两个空瓶可以置换一瓶汽水,现有N元,最多能喝多少瓶?