[HNOI2015]开店

LG传送门

蒟蒻表示不会动态淀粉质。

先把点按年龄排序, 设\(dis[i]\)表示\(i\)到根的距离。

把我们要算的东西稍微变下形:\(ans\)

\[= \sum \limits _{i = l} ^r (dis[i] + dis[u] - 2 * dis[lca(i, u)]
\]

\[= \sum \limits _{i = l} ^r dis[i] + (r - l + 1) * dis[u] - 2 * \sum \limits _{i = l} ^r dis[lca(i, u)]
\]

前面两项都很容易算,主要是最后一项不太好弄,假设我们能快速求出\(\sum \limits _{i = 1} ^n dis[lca(i, u)]\),那么我们就可以套上一个主席树解决这个问题,考虑树剖,对于每个点将这个点到根路径上的点权值加一,维护每个点的权值乘以其父边的权值的区间和,查询的时候就算一下询问点到根的路径上线段树所维护的信息和就行了。

主席树需要标记永久化。

//written by newbiechd
#include <cstdio>
#include <cctype>
#include <vector>
#include <algorithm>
#define R register
#define I inline
#define B 1000000
#define L long long
using namespace std;
const int N = 150003;
char buf[B], *p1, *p2;
I char gc() { return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, B, stdin), p1 == p2) ? EOF : *p1++; }
I int rd() {
R int f = 0;
R char c = gc();
while (c < 48 || c > 57)
c = gc();
while (c > 47 && c < 58)
f = f * 10 + (c ^ 48), c = gc();
return f;
}
int s[N], dep[N], fa[N], lst[N], siz[N], son[N], dfn[N], top[N], rt[N], n, tim, T, tmp;
L dis[N], sum[N], val[N], ans;
struct node {
int p, d;
node () {}
node (int p, int d) : p(p), d(d) {}
}a[N];
struct segtree {
int p, q, d;
L s;
}e[N << 7];
vector <pair <int, int> > g[N];
I int operator < (node x, node y) { return x.d ^ y.d ? x.d < y.d : x.p < y.p; }
I void swap(int &x, int &y) { x ^= y, y ^= x, x ^= y; }
void dfs1(int x, int f) {
dep[x] = dep[f] + 1, dis[x] = dis[f] + lst[x], fa[x] = f, siz[x] = 1;
for (R int i = 0, y, m = 0; i < s[x]; ++i)
if ((y = g[x][i].first) ^ f) {
lst[y] = g[x][i].second, dfs1(y, x), siz[x] += siz[y];
if (siz[y] > m)
m = siz[y], son[x] = y;
}
}
void dfs2(int x, int t) {
dfn[x] = ++tim, val[tim] = lst[x], top[x] = t;
if (son[x])
dfs2(son[x], t);
for (R int i = 0, y; i < s[x]; ++i)
if (!dfn[y = g[x][i].first])
dfs2(y, y);
}
int insert(int k, int l, int r, int x, int y) {
R int t = ++T;
e[t] = e[k];
if (x == l && y == r) {
++e[t].d;
return t;
}
e[t].s += val[y] - val[x - 1];
R int m = (l + r) >> 1;
if (y <= m)
e[t].p = insert(e[k].p, l, m, x, y);
else
if (m < x)
e[t].q = insert(e[k].q, m + 1, r, x, y);
else
e[t].p = insert(e[k].p, l, m, x, m),
e[t].q = insert(e[k].q, m + 1, r, m + 1, y);
return t;
}
L query(int k, int l, int r, int x, int y) {
L o = 1ll * (val[y] - val[x - 1]) * e[k].d;
if (x == l && y == r)
return o + e[k].s;
R int m = (l + r) >> 1;
if (y <= m)
return o + query(e[k].p, l, m, x, y);
if (m < x)
return o + query(e[k].q, m + 1, r, x, y);
return o + query(e[k].p, l, m, x, m) + query(e[k].q, m + 1, r, m + 1, y);
}
I void modify(int x) {
while (x)
tmp = insert(tmp, 1, n, dfn[top[x]], dfn[x]), x = fa[top[x]];
}
I L calc(int x, int root) {
L o = 0;
while (x)
o += query(root, 1, n, dfn[top[x]], dfn[x]), x = fa[top[x]];
return o;
}
int main() {
R int Q, A, i, x, y, z;
n = rd(), Q = rd(), A = rd();
for (i = 1; i <= n; ++i)
a[i]= node(i, rd());
for (i = 1; i < n; ++i)
x = rd(), y = rd(), z = rd(),
g[x].push_back(make_pair(y, z)), g[y].push_back(make_pair(x, z));
for (i = 1; i <= n; ++i)
s[i] = g[i].size();
dfs1(1, 0), dfs2(1, 1), sort(a + 1, a + n + 1);
for (i = 1; i <= n; ++i)
sum[i] = sum[i - 1] + dis[a[i].p], val[i] += val[i - 1];
for (i = 1; i <= n; ++i)
modify(a[i].p), rt[i] = tmp;
for (i = 1; i <= Q; ++i) {
x = rd(), y = (ans + rd()) % A, z = (ans + rd()) % A;
if (y > z)
swap(y, z);
y = lower_bound(a + 1, a + n + 1, node(0, y)) - a,
z = upper_bound(a + 1, a + n + 1, node(N, z)) - a - 1;
printf("%lld\n", ans = 1ll * (z - y + 1) * dis[x] + sum[z] - sum[y - 1]
- 2ll * (calc(x, rt[z]) - calc(x, rt[y - 1])));
}
return 0;
}

[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. Jquery的跨域调用

    JQuery1.2后getJSON方法支持跨域读取json数据,原理是利用一个叫做jsonp的概念.当然,究其本质还是通过script标签动态加载js,似乎这是实现真正跨域的唯一方法. getJSON ...

  2. UNIX高级环境编程(5)Files And Directories - 文件相关时间,目录文件相关操作

     1 File Times 每个文件会维护三个时间字段,每个字段代表的时间都不同.如下表所示: 字段说明: st_mtim(the modification time)记录了文件内容最后一次被修改的时 ...

  3. Linux系统锁定关键文件

    锁定系统关键文件 1.密码.账号文件 chattr +i /etc/passwd /etc/group /etc/shadow /etc/gshadow /etc/inittab 加锁:chattr ...

  4. 【2017-11-19】Linux基础知识:TP-Link WN823N无线网卡(RTL8192EU芯片)的X86-64及AARCH64驱动安装

    目的: 使类似于树莓派的AARCH-64架构的嵌入式设备能通过USB无线网卡连接上以太网: 该设备有LAN接口,但在前一次系统固件升级后,其内部的三个网络接口可以相互ping通,但任一接口无法ping ...

  5. 如何处理高并发情况下的DB插入

    1.  我们需要接收一个外部的订单,而这个订单号是不允许重复的 2.  数据库对外部订单号没有做唯一性约束 3.  外部经常插入相同的订单,对于已经存在的订单则拒绝处理 对于这个需求,很简单我们会用下 ...

  6. Python的网络编程 Socket编程

    Socket是进程间通信的一种方式,与其他进程间通信的一个主要不同是:能实现不同主机间的进程间通信,网络上各种各样的服务大多都是基于Socket来完成通信的,要解决网络上两台主机间的通信问题,首先要唯 ...

  7. eclipse中文乱码解决

    1. 改变整个文件类型的编码格式 1)  eclipse->window->preferences->General->Content Types    2)  找到要修改的文 ...

  8. List集合和iterator并发异常处理

    一:List接口: 子类:ArrayList   LinkedList 特点:Unlike sets, lists typically allow duplicate elements.不像set集合 ...

  9. 工程脚本插件方案 - c集成Python基础篇

    序: 为什么要集成脚本,怎么在工程中集成Python脚本. 在做比较大型的工程时,一般都会分核心层和业务层.核心层要求实现高效和稳定的基础功能,并提供调用接口供业务层调用的一种标准的框架划分.在实际中 ...

  10. linux文件系统初始化过程(5)---加载initrd(下)

    一.目的 linux把文件分为常规文件.目录文件.软链接文件.硬链接文件.特殊文件(设备文件.管道文件.socket文件等)几种类型,分别对应不同的新建函数sys_open().sys_mkdir() ...