考场上写了lct,可惜当时对标记永久化的理解并不是十分深刻,导致调一个错误的程序调了4h+,最后这道题爆0了QwQ

现在写了树链剖分,用标记永久化的线段树维护轻重链,对于$s\rightarrow lca$,$lca\rightarrow t$分开讨论,把$a×dist+b$这个式子打开,提出常数项,发现是一个一次函数(也不是严格的一次函数,只不过有单调性就可以做了)。标记永久化线段树做一下,每个节点维护一个当前区间的最小值就可以统计答案了233

这次又手残把“+”打成“*”调了一上午TwT,肉眼对拍大法好!

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long LL;
const int N = 100005;
const LL inf = 123456789123456789LL;
void read(int &k) {
k = 0; int fh = 1; char c = getchar();
for(; c < '0' || c > '9'; c = getchar())
if (c == '-') fh = -1;
for(; c >= '0' && c <= '9'; c = getchar())
k = (k << 1) + (k << 3) + c - '0';
k = k * fh;
} struct node {
int nxt, to, w;
} E[N << 1];
int n, m, cnt = 0, point[N], fa[N], top[N], son[N], sz[N], pos[N], wt[N], K[N << 2];
LL B[N << 2], val[N << 2], di[N], ans;
bool p[N << 2];
void ins(int x, int y, int z) {E[++cnt].nxt = point[x]; E[cnt].to = y; E[cnt].w = z; point[x] = cnt;}
void _(int x) {
sz[x] = 1;
for(int tmp = point[x]; tmp; tmp = E[tmp].nxt)
if (E[tmp].to != fa[x]) {
fa[E[tmp].to] = x;
di[E[tmp].to] = di[x] + E[tmp].w;
_(E[tmp].to);
sz[x] += sz[E[tmp].to];
if (sz[E[tmp].to] > sz[son[x]]) son[x] = E[tmp].to;
}
}
void __(int x) {
pos[x] = ++cnt; wt[cnt] = x;
if (son[x]) {top[son[x]] = top[x]; __(son[x]);}
for(int tmp = point[x]; tmp; tmp = E[tmp].nxt)
if (E[tmp].to != fa[x] && E[tmp].to != son[x])
{top[E[tmp].to] = E[tmp].to; __(E[tmp].to);}
}
int LCA(int x, int y) {
for(; top[x] != top[y]; x = fa[top[x]])
if (di[top[x]] < di[top[y]]) swap(x, y);
return di[x] < di[y] ? x : y;
}
void pushup(int rt, int l, int r) {
if (l < r) val[rt] = min(val[rt << 1], val[rt << 1 | 1]); else val[rt] = inf;
if (p[rt]) val[rt] = min(val[rt], min(di[wt[l]] * K[rt], di[wt[r]] * K[rt]) + B[rt]);
}
void Build(int rt, int l, int r) {
val[rt] = inf;
if (l == r) return;
int mid = (l + r) >> 1;
Build(rt << 1, l, mid);
Build(rt << 1 | 1, mid + 1, r);
} void update(int rt, int l, int r, int a, LL b) {
if (!p[rt]) {
p[rt] = 1; K[rt] = a; B[rt] = b;
} else {
LL newl = a * di[wt[l]] + b, newr = a * di[wt[r]] + b, befl = K[rt] * di[wt[l]] + B[rt], befr = K[rt] * di[wt[r]] + B[rt];
int mid = (l + r) >> 1;
if (newl <= befl && newr <= befr) {
K[rt] = a; B[rt] = b;
} else
if (newl >= befl && newr >= befr)
return;
else
if (a < K[rt]) {
double tmp = (b - B[rt]) / (K[rt] - a);
if (tmp <= di[wt[mid]]) {
update(rt << 1, l, mid, K[rt], B[rt]);
K[rt] = a; B[rt] = b;
} else
update(rt << 1 | 1, mid + 1, r, a, b);
} else {
double tmp = (B[rt] - b) / (a - K[rt]);
if (tmp > di[wt[mid]]) {
update(rt << 1 | 1, mid + 1, r, K[rt], B[rt]);
K[rt] = a; B[rt] = b;
} else
update(rt << 1, l, mid, a, b);
}
}
pushup(rt, l, r);
} void inc(int rt, int l, int r, int L, int R, int a, LL b) {
if (L <= l && r <= R) {update(rt, l, r, a, b); return;}
int mid = (l + r) >> 1;
if (L <= mid) inc(rt << 1, l, mid, L, R, a, b);
if (R > mid) inc(rt << 1 | 1, mid + 1, r, L, R, a, b);
pushup(rt, l, r);
}
void Q(int rt, int l, int r, int L, int R) {
if (L == l && r == R) {ans = min(ans, val[rt]); return;}
if (p[rt]) ans = min(ans, min(K[rt] * di[wt[L]], K[rt] * di[wt[R]]) + B[rt]);
int mid = (l + r) >> 1;
if (R <= mid) Q(rt << 1, l, mid, L, R);
else if (L > mid) Q(rt << 1 | 1, mid + 1, r, L, R);
else {Q(rt << 1, l, mid, L, mid); Q(rt << 1 | 1, mid + 1, r, mid + 1, R);}
} int main() {
read(n); read(m); int u, v, e, a, b, lca;
for(int i = 1; i < n; ++i) {
read(u); read(v); read(e);
ins(u, v, e); ins(v, u, e);
} _(1);
cnt = 0; top[1] = 1;
__(1);
Build(1, 1, n); LL tmp;
for(; m; --m) {
read(e);
if (e == 1) {
read(u); read(v); read(a); read(b);
lca = LCA(u, v);
tmp = 1LL * a * di[u] + b;
for(; top[u] != top[lca]; u = fa[top[u]])
inc(1, 1, n, pos[top[u]], pos[u], - a, tmp);
inc(1, 1, n, pos[lca], pos[u], - a, tmp);
tmp -= (di[lca] << 1) * a;
for(; top[v] != top[lca]; v = fa[top[v]])
inc(1, 1, n, pos[top[v]], pos[v], a, tmp);
inc(1, 1, n, pos[lca], pos[v], a, tmp);
} else {
ans = inf; read(u); read(v);
for(; top[u] != top[v]; u = fa[top[u]]) {
if (di[top[u]] < di[top[v]]) swap(u, v);
Q(1, 1, n, pos[top[u]], pos[u]);
}
if (di[u] > di[v]) swap(u, v);
Q(1, 1, n, pos[u], pos[v]);
printf("%lld\n", ans);
}
}
return 0;
}

Round2加油!

【BZOJ 4515】【SDOI 2016 Round1 Day1 T3】游戏的更多相关文章

  1. 【BZOJ 4598】【SDOI 2016 Round2 Day1 T3】模式字符串

    2016-05-21因为BZOJ上“ 数据文件太过巨大,仅提供前三组数据测试.”所以我考场上写的60分的点分治交上去也A了. 我的这个点分治的时间复杂度是$O(Tnmlogn)$的,听题解时没听懂$O ...

  2. 【BZOJ 4518】【SDOI 2016 Round1 Day2 T3】征途

    比较明显的斜率优化DP,省选时因为时间太紧张和斜率DP写得不熟等原因只写了60分的暴力DP,其实当时完全可以对拍来检验标算的正确,但是我当时too naive- 很快打完了,调了将近一晚上QAQ,因为 ...

  3. SDOI 2016 Round1 Day1

    储能表 /* 引自zyz大佬的数学思想 */ #include<cstdio> #include<iostream> using namespace std; typedef ...

  4. 【BZOJ 4517】【SDOI 2016 Round1 Day2 T2】排列计数

    本蒟蒻第一次没看题解A的题竟然是省选$Round1$ $Day2$ $T2$ 这道组合数学题. 考试时一开始以为是莫队,后来想到自己不会组合数的一些公式,便弃疗了去做第三题,,, 做完第三题后再回来看 ...

  5. 【NOIP 2015 & SDOI 2016 Round1 & CTSC 2016 & SDOI2016 Round2】游记

    我第一次写游记,,,, 正文在哪里?正文在哪里?正文在哪里?正文在哪里?正文在哪里?正文在哪里?正文在哪里?正文在哪里?正文在哪里?正文在哪里?正文在哪里?正文在哪里?正文在哪里?正文在哪里?正文在哪 ...

  6. [BZOJ 4516] [SDOI 2016] 生成魔咒

    Description 魔咒串由许多魔咒字符组成,魔咒字符可以用数字表示.例如可以将魔咒字符 1.2 拼凑起来形成一个魔咒串 [1,2]. 一个魔咒串 S 的非空字串被称为魔咒串 S 的生成魔咒. 例 ...

  7. SDOI 2016 Round1 Day2

    生成魔咒 /* 后缀数组+双向链表 参照:https://blog.csdn.net/clove_unique/article/details/53911757 */ #include<cstd ...

  8. 【NOIP2016】Day1 T3 换教室(期望DP)

    题目背景 NOIP2016 提高组 Day1 T3 题目描述 对于刚上大学的牛牛来说,他面临的第一个问题是如何根据实际情况申请合适的课程. 在可以选择的课程中,有 2n 节课程安排在 n 个时间段上. ...

  9. [BZOJ 1879][SDOI 2009]Bill的挑战 题解(状压DP)

    [BZOJ 1879][SDOI 2009]Bill的挑战 Description Solution 1.考虑状压的方式. 方案1:如果我们把每一个字符串压起来,用一个布尔数组表示与每一个字母的匹配关 ...

随机推荐

  1. USACO Sorting a Three-Valued Sequence

    题目描述 排序是一种很频繁的计算任务.现在考虑最多只有三值的排序问题.一个实际的例子是,当我们给某项竞赛的优胜者按金银铜牌排序的时候.在这个任务中可能的值只有三种1,2和3.我们用交换的方法把他排成升 ...

  2. java 24 - 2 GUI之监听机制和适配器改进窗口关闭

    我们创建了窗体后,就要对窗体进行操作,比如关闭窗口.而这时候就要建立监听机制: 事件监听机制: A:事件源 事件发生的地方 B:事件 就是要发生的事情 C:事件处理 就是针对发生的事情做出的处理方案 ...

  3. HTML 学习笔记 CSS(列表)

    CSS列表属性允许你放置 改变列表项标志 或者将图像作为列表项标志. CSS列表 从某中意义上讲 不是描述性的文本的任何内容都可以认为是列表.人口普查.太阳系.家谱.参观菜单,甚至你的所有朋友都可以表 ...

  4. ONS C++ Windows SDK 调试方法及注意事项

    此文将展示ONS C++ Windows SDK 整个调试过程,笔者直接使用sdk包中的example消息发送示例代码,开发环境为win7, 64位,Visual Studio Professiona ...

  5. nginx负载均衡集群中的session共享说明

    在网站使用nginx+php做负载均衡情况下,同一个IP访问同一个页面会被分配到不同的服务器上,如果session不同步的话,就会出现很多问题,比如说最常见的登录状态. 下面罗列几种nginx负载均衡 ...

  6. 033医疗项目-模块三:药品供应商目录模块——供货商药品目录t添加查询功能----------Dao层和Service层和Action层和调试

    什么叫做供货商药品目录t添加查询功能?就是说我们前面的博客里面不是说供货商登录后看到了自己供应的药品了么如下: 现在供货商想要往里面添加别的药品,那么这个药品的来源就是卫生局提供的那个Ypxx表(药品 ...

  7. K8 系统中省市县数据表的设计可以反映出什么? 通过一个基础业务表的设计品味软件系统的整体架构

    1:没有严谨的Id思想,不变化的Id思想,看不见的Id的思想. 2:数据不严谨,没有上下级关系,没有树形结构,ParentId 的思想. 3:表之间的关系都是弱关联,基础数据一修改业务数据就容易乱套. ...

  8. mac:在当前文件夹打开terminal终端

    System Preferences -> Keyboard -> Shortcuts -> Services -> New Terminal at Folders/New T ...

  9. 【软件编程】乐易贵宾VIP教程 - JS改写+网页操作系列教程

    JS改写系列教程: 1.MD5加密改写教程(爱拍网登录)2.解密如何快速找到真确的js加密算法3.多重MD5加密改写教程(5173登录)4.DZ论坛登录加密改写5.唯品会手机登录加密改写6.新浪微博密 ...

  10. 从零开始搭建架构实施Android项目

    我们先假设一个场景需求:刚有孩子的爸爸妈妈对用照片.视频记录宝宝成长有强烈的意愿,但苦于目前没有一款专门的手机APP做这件事.A公司洞察到市场需求,要求开发团队尽快完成Android客户端的开发.以下 ...