主席树。

推下式子,发现点的深度和好算,lca深度和不好算。

lca深度之和有个套路:先给a到根路径+1,再算b到根的和。

如果可以离线,即LNOI的LCA。本题强制在线,可持久化。

由于区间修改,使用标记永久化。

注意修改要复制全,关于和的修改有些细节:

int xiugai(int i, int j, int l, int r, int L, int R) {
if (R <= l || r <= L) return i;
int rt = ++sl;
cl[rt] = cl[i]; cr[rt] = cr[i];
he[rt] = he[i]; ld[rt] = ld[i];
if (L <= l && r <= R) {
he[rt] += su[j];
ld[rt] = ld[i] + 1;
return rt;
}
int m = (l + r) >> 1;
he[rt] -= (he[cl[rt]] + he[cr[rt]]);
cl[rt] = xiugai(cl[rt], j << 1, l, m, L, R);
cr[rt] = xiugai(cr[rt], (j << 1) | 1, m, r, L, R);
he[rt] += (he[cl[rt]] + he[cr[rt]]);
return rt;
}

正常空间需要4倍mlogn:修改区间拆分2倍,上传2倍。应该跑不满。

然而本题是树剖,跑不满,所以开到\(2.5*10^7\)就行。

代码:

#include <stdio.h>
#include <stdlib.h>
#define M 20000010
#define ll long long
#define re register
inline int max(int a, int b) {
return a > b ? a: b;
}
inline int min(int a, int b) {
return a < b ? a: b;
}
inline int read() {
re char ch;
while ((ch = getchar()) == '\n' || ch == ' ' || ch == '\r');
re int jg = ch - '0';
while ((ch = getchar()) >= '0' && ch <= '9') jg = (jg << 3) + (jg << 1) + ch - '0';
return jg;
}
int fr[150010],ne[300010],v[300010],w[300010],bs = 0;
void addb(int a, int b, int c) {
v[bs] = b;
w[bs] = c;
ne[bs] = fr[a];
fr[a] = bs++;
}
int fa[150010],son[150010],sd[150010],cd[150010],jl[150010];
int dfs1(int u, int f) {
fa[u] = f;
sd[u] = sd[f] + 1;
jl[u] = jl[f] + cd[u];
int ma = -1,he = 1;
son[u] = -1;
for (int i = fr[u]; i != -1; i = ne[i]) {
if (v[i] == f) continue;
cd[v[i]] = w[i];
int rt = dfs1(v[i], u);
he += rt;
if (rt > ma) {
ma = rt;
son[u] = v[i];
}
}
return he;
}
int top[150010],bh[150010],tm = 0;
void dfs2(int u, int f, int tp) {
top[u] = tp;
bh[u] = ++tm;
if (son[u] == -1) return;
dfs2(son[u], u, tp);
for (int i = fr[u]; i != -1; i = ne[i]) {
if (v[i] != f && v[i] != son[u]) dfs2(v[i], u, v[i]);
}
}
int js[150010],cl[M],cr[M],ld[M],sl = 0,su[600010];
ll he[M],jh[150010];
void jianshu(int i, int l, int r) {
if (l + 1 == r) {
su[i] = js[l];
return;
}
int m = (l + r) >> 1;
jianshu(i << 1, l, m);
jianshu((i << 1) | 1, m, r);
su[i] = su[i << 1] + su[(i << 1) | 1];
}
int jianshu(int l, int r) {
int rt = ++sl;
he[rt] = ld[rt] = 0;
if (l + 1 == r) return rt;
int m = (l + r) >> 1;
cl[rt] = jianshu(l, m);
cr[rt] = jianshu(m, r);
return rt;
}
int build(int n) {
for (int i = 1; i <= n; i++) js[bh[i]] = cd[i];
jianshu(1, 1, n + 1);
return jianshu(1, n + 1);
}
int xiugai(int i, int j, int l, int r, int L, int R) {
if (R <= l || r <= L) return i;
int rt = ++sl;
cl[rt] = cl[i]; cr[rt] = cr[i];
he[rt] = he[i]; ld[rt] = ld[i];
if (L <= l && r <= R) {
he[rt] += su[j];
ld[rt] = ld[i] + 1;
return rt;
}
int m = (l + r) >> 1;
he[rt] -= (he[cl[rt]] + he[cr[rt]]);
cl[rt] = xiugai(cl[rt], j << 1, l, m, L, R);
cr[rt] = xiugai(cr[rt], (j << 1) | 1, m, r, L, R);
he[rt] += (he[cl[rt]] + he[cr[rt]]);
return rt;
}
ll getsum(int i, int j, int l, int r, int L, int R, int lh) {
if (R <= l || r <= L) return 0;
if (L <= l && r <= R) return 1ll * lh * su[j] + he[i];
int m = (l + r) >> 1;
return getsum(cl[i], j << 1, l, m, L, R, lh + ld[i]) + getsum(cr[i], (j << 1) | 1, m, r, L, R, lh + ld[i]);
}
int xiugai(int od, int x, int n) {
while (x != 0) {
od = xiugai(od, 1, 1, n + 1, bh[top[x]], bh[x] + 1);
x = fa[top[x]];
}
return od;
}
ll getsum(int ro, int x, int n) {
ll jg = 0;
while (x != 0) {
jg += getsum(ro, 1, 1, n + 1, bh[top[x]], bh[x] + 1, 0);
x = fa[top[x]];
}
return jg;
}
struct SPx {
int z, i;
};
SPx px[150010];
int cmp(const void * a, const void * b) {
return ((SPx * ) a) ->z - ((SPx * ) b) ->z;
}
int find(int n, int x) {
int l = 0, r = n;
while (l < r) {
int m = (l + r + 1) >> 1;
if (px[m].z <= x) l = m;
else r = m - 1;
}
return l;
}
int gen[150010];
ll getans(int L, int R, int u, int n) {
int r = find(n, R);
int l = find(n, L - 1);
ll lc = getsum(gen[r], u, n) - getsum(gen[l], u, n);
ll jg = 1ll * (r - l) * jl[u] + (jh[r] - jh[l]) - lc * 2;
return jg;
}
void insert(int i, int n) {
gen[i] = xiugai(gen[i - 1], px[i].i, n);
jh[i] = jh[i - 1] + jl[px[i].i];
}
int main() {
int n, q, m;
ll la = 0;
scanf("%d%d%d", &n, &q, &m);
for (int i = 1; i <= n; i++) {
fr[i] = -1;
px[i].i = i;
px[i].z = read();
}
qsort(px + 1, n, sizeof(SPx), cmp);
for (int i = 0; i < n - 1; i++) {
int a, b, c;
a = read();
b = read();
c = read();
addb(a, b, c);
addb(b, a, c);
}
dfs1(1, 0);
dfs2(1, 0, 1);
gen[0] = build(n);
for (int i = 1; i <= n; i++) insert(i, n);
for (int i = 0; i < q; i++) {
int u, a, b;
u = read();
a = read();
b = read();
int L = min((a + la) % m, (b + la) % m);
int R = max((a + la) % m, (b + la) % m);
la = getans(L, R, u, n);
printf("%lld\n", la);
}
return 0;
}

[HNOI2015]开店 简要题解的更多相关文章

  1. A · F · O —— JLOI2018翻车记(附Day1简要题解)

    JLOI2018翻车记 并不知道该怎么写... 算了还是按照标准剧情来吧 这应该是一篇写得非常差的流水账... 2018.04.04 Day -1 省选前在机房的最后一天. 压力并不是很大,毕竟联赛 ...

  2. 【BZOJ4012】[HNOI2015]开店 动态树分治+二分

    [BZOJ4012][HNOI2015]开店 Description 风见幽香有一个好朋友叫八云紫,她们经常一起看星星看月亮从诗词歌赋谈到人生哲学.最近她们灵机一动,打算在幻想乡开一家小店来做生意赚点 ...

  3. HNOI2015 Day 2题解

    昨天做了HNOI day 2,感觉好像还是可做的,想当年什么splay还是高级算法,现在点剖什么就老考了简直丧病,虽然第二题还没写那就先当下嘴巴选手吧= = T1:[HNOI2015]落忆枫音 描述: ...

  4. Noip 2014酱油记+简要题解

    好吧,day2T1把d默认为1也是醉了,现在只能期待数据弱然后怒卡一等线吧QAQ Day0 第一次下午出发啊真是不错,才2小时左右就到了233,在车上把sao和fate补掉就到了= = 然后到宾馆之后 ...

  5. Tsinghua 2018 DSA PA2简要题解

    反正没时间写,先把简要题解(嘴巴A题)都给他写了记录一下. upd:任务倒是完成了,我也自闭了. CST2018 2-1 Meteorites: 乘法版的石子合并,堆 + 高精度. 写起来有点烦貌似. ...

  6. Codeforces 863 简要题解

    文章目录 A题 B题 C题 D题 E题 F题 G题 传送门 简要题解?因为最后一题太毒不想写了所以其实是部分题解... A题 传送门 题意简述:给你一个数,问你能不能通过加前导000使其成为一个回文数 ...

  7. HNOI2018简要题解

    HNOI2018简要题解 D1T1 寻宝游戏 题意 某大学每年都会有一次 Mystery Hunt 的活动,玩家需要根据设置的线索解谜,找到宝藏的位置,前一年获胜的队伍可以获得这一年出题的机会. 作为 ...

  8. JXOI2018简要题解

    JXOI2018简要题解 T1 排序问题 题意 九条可怜是一个热爱思考的女孩子. 九条可怜最近正在研究各种排序的性质,她发现了一种很有趣的排序方法: Gobo sort ! Gobo sort 的算法 ...

  9. BJOI2018简要题解

    BJOI2018简要题解 D1T1 二进制 题意 pupil 发现对于一个十进制数,无论怎么将其的数字重新排列,均不影响其是不是 \(3\) 的倍数.他想研究对于二进制,是否也有类似的性质. 于是他生 ...

随机推荐

  1. 路由器设置 WDS 桥接

    步骤: 1.先更改路由器LAN口地址,然后重启路由器 2.连接SSID信道名称,先关闭DHCP服务,然后进入无线设置,基本设置,更改SSID号,开启WDS桥接,保存 3.连接新的SSID名称,无线设置 ...

  2. Linux下的静态库与动态库的生成与调用

    静态库与动态库 静态函数库 这类库的名字一般是libxxx.a,xxx为库的名字.利用静态函数库编译成的文件比较大,因为整个函数库的所有数据都会被整合进目标代码中,他的优点就显而易见了,即编译后的执行 ...

  3. logstash grok nginx log

    #cat logstash.conf input { file { path => "/alidata/logs/nginx/appapi.dayutang.cn.access*.lo ...

  4. 笔记-8:使用turtle库进行图形绘制

    1.窗体函数 turtle.setup(width,height,startx,starty) 作用:设置窗体的大小和位置 width:窗口宽度,如果值是整数,表示像素值:如果值是小数,表示窗口宽度与 ...

  5. TZOJ数据结构实验:左叶子之和

    int sumOfLeftLeaves(struct TreeNode* root) { if (root == NULL) { ; }//递归结束条件 if (root->left & ...

  6. 数据库设计_ERMaster安装使用_PowerDesigner数据设计工具

    数据库设计 1. 说在前面 项目开发的流程包括哪些环节 需求调研[需求调研报告]-- 公司决策层 (1) 根据市场公司需求分析公司是否需要开发软件来辅助日常工作 (2) 公司高层市场考察,市场分析,决 ...

  7. Linux 编译kernel有关Kconfig文件详解

    ref : https://blog.csdn.net/Ultraman_hs/article/details/52984929 Kconfig的格式 下面截取/drivers/net下的Kconfi ...

  8. JS OOP -01 面向对象的基础

    JS面向对象的基础: 1.用定义函数的方式定义类 2.用new操作符获得一个类的实例 3.使用 [ ] 引用对象的属性和方法 4.动态添加,修改,删除对象的属性和方法 5.使用 { } 语法创建无类型 ...

  9. VS2019打开项目加载失败:无法找到 .NET Core SDK。请检查确保已安装此项且 global.json 中指定的版本(如有)与所安装的版本相匹配。

    问题描述: 用VS2019创建了asp.net core项目,正常运行:过几天后,再次打开,发现无法加载项目,报错无法找到.net core sdk.   分析过程: 首先怀疑环境变量的问题,重新设置 ...

  10. 经典SQL数据库面试题以及答案—Oracle版本-SQL全部在plsql开发编写-欢迎提问

    Student(Sno,Sname,Sage,Ssex) 学生表 S1:学号:Sname:学生姓名:Sage:学生年龄:Ssex:学生性别 Course(Cno,Cname,T1) 课程表 C1,课程 ...