#6073. 「2017 山东一轮集训 Day5」距离(树链剖分 + 永久标记主席树)
#6073. 「2017 山东一轮集训 Day5」距离
由于强制在线,所以这题必须用主席树,我们定义点iii所代表的主席树为从1−>i1->i1−>i上,也就是根节点到iii上,
#include <bits/stdc++.h>using namespace std;typedef long long ll;const int N = 2e5 + 10;int head[N], to[N << 1], nex[N << 1], value[N << 1], cnt = 1;int p[N], n, m, type;int fa[N], sz[N], son[N], top[N], rk[N], id[N], dep[N], w[N], tot;int root[N], ls[N * 100], rs[N * 100], num;ll dis[N], len[N], s[N], sum[N * 100], lazy[N * 100];void add(int x, int y, int w) {to[cnt] = y;nex[cnt] = head[x];value[cnt] = w;head[x] = cnt++;
}void dfs1(int rt, int f) {fa[rt] = f, dep[rt] = dep[f] + 1, sz[rt] = 1;for (int i = head[rt]; i; i = nex[i]) {if (to[i] == f) {continue;}dis[to[i]] = dis[rt] + value[i];dfs1(to[i], rt);w[to[i]] = value[i];sz[rt] += sz[to[i]];if (!son[rt] || sz[son[rt]] < sz[to[i]]) {son[rt] = to[i];}}
}void dfs2(int rt, int tp) {rk[++tot] = rt, id[rt] = tot, len[tot] = w[rt], top[rt] = tp;if (!son[rt]) {return ;}dfs2(son[rt], tp);for (int i = head[rt]; i; i = nex[i]) {if (to[i] == fa[rt] || to[i] == son[rt]) {continue;}dfs2(to[i], to[i]);}
}int lca(int u, int v) {while (top[u] != top[v]) {if (dep[top[u]] < dep[top[v]]) {swap(u, v);}u = fa[top[u]];}return dep[u] < dep[v] ? u : v;
}void update(int &rt, int pre, int l, int r, int L, int R) {rt = ++num;ls[rt] = ls[pre], rs[rt] = rs[pre], sum[rt] = sum[pre], lazy[rt] = lazy[pre];sum[rt] += len[min(r, R)] - len[max(l, L) - 1];if (l >= L && r <= R) {lazy[rt] += 1;return ;}int mid = l + r >> 1;if (L <= mid) {update(ls[rt], ls[pre], l, mid, L, R);}if (R > mid) {update(rs[rt], rs[pre], mid + 1, r, L, R);}
}ll query(int u, int v, int f, int ff, int l, int r, int L, int R) {if (l >= L && r <= R) {return sum[u] + sum[v] - sum[f] - sum[ff];}ll ans = (lazy[u] + lazy[v] - lazy[f] - lazy[ff]) * (len[min(r, R)] - len[max(l, L) - 1]);int mid = l + r >> 1;if (L <= mid) {ans += query(ls[u], ls[v], ls[f], ls[ff], l, mid, L, R);}if (R > mid) {ans += query(rs[u], rs[v], rs[f], rs[ff], mid + 1, r, L, R);}return ans;
}void dfs(int rt, int f) {s[rt] = s[f] + dis[p[rt]];int cur = p[rt];root[rt] = root[f];while (cur) {update(root[rt], root[rt], 1, n, id[top[cur]], id[cur]);cur = fa[top[cur]];}for (int i = head[rt]; i; i = nex[i]) {if (to[i] == f) {continue;}dfs(to[i], rt);}
}ll query(int u, int v, int f, int ff, int rt) {ll ans = 0;while (rt) {ans += query(root[u], root[v], root[f], root[ff], 1, n, id[top[rt]], id[rt]);rt = fa[top[rt]];}return ans;
}int main() {// freopen("in.txt", "r", stdin);// freopen("out.txt", "w", stdout);scanf("%d %d %d", &type, &n, &m);for (int i = 1, u, v, w; i < n; i++) {scanf("%d %d %d", &u, &v, &w);add(u, v, w);add(v, u, w);}for (int i = 1; i <= n; i++) {scanf("%d", &p[i]);}dfs1(1, 0);dfs2(1, 1);for (int i = 1; i <= n; i++) {len[i] += len[i - 1];}dfs(1, 0);ll ans = 0;for (int i = 1, u, v, k; i <= m; i++) {scanf("%d %d %d", &u, &v, &k);u = u ^ (ans * type), v = v ^ (ans * type), k = k ^ (ans * type);int f = lca(u, v), ff = fa[f];ans = (dep[u] + dep[v] - dep[f] - dep[ff]) * dis[k];ans += s[u] + s[v] - s[f] - s[ff];ans -= 2 * query(u, v, f, ff, k);printf("%lld\n", ans);}return 0;
}
#6073. 「2017 山东一轮集训 Day5」距离(树链剖分 + 永久标记主席树)相关推荐
- 「2017 山东一轮集训 Day5」距离
/* 写完开店再写这个题目顿时神清气爽, 腰也不疼了, 眼也不花了首先考虑将询问拆开, 就是查询一些到根的链和点k的关系根据我们开店的结论, 一个点集到一个定点的距离和可以分三部分算 那么就很简单了吧 ...
- LOJ#6072. 「2017 山东一轮集训 Day5」苹果树 解题报告
LOJ#6072. 「2017 山东一轮集训 Day5」苹果树 解题报告 好苹果会组成连通块,整棵树的权值为 ∑ i = 1 n c i [ c i ≥ 0 ] [ s i z n u m ( c i ...
- Loj #6077. 「2017 山东一轮集训 Day7」逆序对
Loj #6077. 「2017 山东一轮集训 Day7」逆序对 Solution 令fi,jf_{i,j}fi,j表示前iii个数产生jjj个逆序对的方案数,每次考虑把i+1i+1i+1加入,有i ...
- 容斥问卷调查反馈——Co-prime,Character Encoding,Tree and Constraints,「2017 山东一轮集训 Day7」逆序对
文章目录 Co-prime source solution code Character Encoding source solution code Tree and Constraints sour ...
- 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⋯ ...
- LOJ#6103. 「2017 山东二轮集训 Day2」第一题 解题报告
LOJ#6103. 「2017 山东二轮集训 Day2」第一题 解题报告 前置知识:闭区间上的连续函数的零点存在性定理: 我们定义这样的函数: 定义域为 [ l , r ] ∩ Z [l,r]\cap ...
- LOJ6079「2017 山东一轮集训 Day7」养猫
养ImmortalCO k可重区间问题 的增强版:有上下界! 直接都选择s[i],然后再把一些调整到e[i] 考虑通过最大流的"最大",使得至少每k个有me个e, 通过最大流的&q ...
- [LOJ#6068]. 「2017 山东一轮集训 Day4」棋盘[费用流]
题意 题目链接 分析 考虑每个棋子对对应的横向纵向的极大区间的影响:记之前这个区间中的点数为 \(x\) ,那么此次多配对的数量即 \(x\) . 考虑费用流,\(S\rightarrow 横向区间 ...
- 「2017 山东一轮集训 Day2」Pair (霍尔定理+线段树)
题目描述 给出一个长度为 的数列 和一个长度为 的数列 ,求 有多少个长度为 的连续子数列能与 匹配. 两个数列可以匹配,当且仅当存在一种方案,使两个数列中的数可以两两配对,两个数可以配对 ...
最新文章
- do还是doing imagine加to_中学必背英语短语集合:54个doing动名词的固定搭配
- 同步代码时忽略maven项目 target目录
- DM6467T开发板领航——开发环境
- 关于python保存再打开后的中文乱码的问题
- 如何学习Android系统源码
- android信鸽推送demo_腾讯信鸽Android推送集成全解
- python爬虫与反爬虫
- ideaIU-2020.3.2安装教程以及导入第一个spring boot项目运行和环境配置教程
- arcgis api 4.X 比例尺的添加
- 谁说程序员年龄大了,就没出路了?
- 全球最顶级的管理模式全在这了
- [益智]:空姐分配物品
- 提高网站打开速度的7大秘诀
- Linux线程条件控制实现线程的同步pthread_cond_init、pthread_cond_destroy、pthread_cond_wait、pthread_cond_signal
- pushplus 开放接口文档
- 想要风投被你的融资 PPT 打动吗?别忘了你其实就是在想方设法卖出自己公司的部分股权...
- 上阳MSN手机客户端测试版(README)
- 金仓数据库 KingbaseGIS 使用手册(6.11. 空间关系函数)
- JavaScript的eval()方法的使用
- 采用面向对象方法开发软件,通常需要建立三种形式的模型
热门文章
- redis php方案,Redis三种部署方案图文详解
- 理科都要学大学计算机吗,女生不适合学理科专业?报考这些理科专业,一毕业就会遭到疯抢!...
- java list 初始化_Java新特性:数据类型可以扔掉了?
- 阿基米德椭圆规原理,你看懂了吗?
- 这才是老公的正确用法,不吃就往死里打......
- 绝对不能错过!2009~2019 高中数学联赛11年真题解析
- 别太贪婪,这些技能能让你一辈子满足
- 如何把朋友升级成情侣?| 今日最佳
- 阿里日均纳税超1.4亿;AI换脸骗过美侦查;日本民众哄抢令和报纸;辟谣教学楼发现大量金矿;上海拨通首个5G通话;这就是今日大新闻...
- linux 文档属于apache,Apache 安装和使用文档