题目大意:

http://www.lydsy.com/JudgeOnline/problem.php?id=4515

题解:

先让我%一发lych大佬点我去看dalao的题解

讲的很详细.

这里纠正一个地方,lych大佬的式子中有一个\(a*(d[s]-d[x])+b=-a*d[x]+(b-a*d[s])\)

应该是\(a*(d[s]-d[x])+b = -a*d[x] + (b+a*d[s])\)

看来是大爷敲式子的时候敲错了...

除去这个就很完美啦

新get了线段树标记永久化的姿势

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
template<typename T>inline void read(T &x){
x=0;char ch;bool flag = false;
while(ch=getchar(),ch<'!');if(ch == '-') ch=getchar(),flag = true;
while(x=10*x+ch-'0',ch=getchar(),ch>'!');if(flag) x=-x;
}
const ll maxn = 210010;
const ll inf = 123456789123456789LL;
struct Edge{
ll to,next;
ll dis;
}G[maxn<<1];
ll head[maxn],cnt;
void add(ll u,ll v,ll d){
G[++cnt].to = v;
G[cnt].next = head[u];
head[u] = cnt;
G[cnt].dis = d;
}
ll son[maxn],siz[maxn],fa[maxn],top[maxn];
ll dfn[maxn],dfs_clock,num[maxn],dep[maxn];
ll d[maxn];
#define v G[i].to
void dfs(ll u){
siz[u] = 1;
for(ll i = head[u];i;i=G[i].next){
if(v == fa[u]) continue;
fa[v] = u;
d[v] = d[u] + G[i].dis;
dep[v] = dep[u] + 1;
dfs(v);
siz[u] += siz[v];
if(siz[son[u]] < siz[v]) son[u] = v;
}
}
void dfs(ll u,ll tp){
top[u] = tp;
dfn[u] = ++dfs_clock;
num[dfs_clock] = u;
if(son[u]) dfs(son[u],tp);
for(ll i = head[u];i;i=G[i].next){
if(v == fa[u] || v == son[u]) continue;
dfs(v,v);
}
}
#undef v
struct Node{
ll k,b,minn;
bool lazy;
Node(){k=lazy=0;b = minn = inf;}
}T[maxn<<2];
ll K,B,L,R;ll n;
ll query(ll rt,ll l,ll r){
if(L <= l && r <= R) return T[rt].minn;
ll ret = inf;
if(T[rt].lazy) ret = min(T[rt].k*d[num[max(L,l)]],T[rt].k*d[num[min(R,r)]]) + T[rt].b;
ll mid = l+r >> 1;
if(L <= mid) ret = min(ret,query(rt<<1,l,mid));
if(R > mid) ret = min(ret,query(rt<<1|1,mid+1,r));
return ret;
}
inline ll query(ll l,ll r){
if(l > r) swap(l,r);
L = l;R = r; return query(1,1,n);
}
void update(ll rt,ll l,ll r,ll K,ll B){
if(T[rt].lazy == 0){
T[rt].k = K;T[rt].b = B;T[rt].lazy = 1;
if(l < r) T[rt].minn = min(T[rt<<1].minn,T[rt<<1|1].minn);
T[rt].minn = min(T[rt].minn,min(T[rt].k*d[num[l]],T[rt].k*d[num[r]])+T[rt].b);
return;
}
ll mid = l+r >> 1;
ll y1 = K*d[num[r]] + B;
ll y2 = T[rt].k*d[num[r]] + T[rt].b;
ll y3 = K*d[num[l]] + B;
ll y4 = T[rt].k*d[num[l]] + T[rt].b;
if(y3 <= y4 && y1 <= y2) T[rt].k = K,T[rt].b = B;
else if(y3 >= y4 && y1 >= y2) return;
else if(T[rt].k > K){
ll x = (B-T[rt].b)/(T[rt].k-K) + 1;
if(x <= d[num[mid]]){
swap(T[rt].b,B);swap(T[rt].k,K);
update(rt<<1,l,mid,K,B);
}else update(rt<<1|1,mid+1,r,K,B);
}else{
ll x = (T[rt].b - B - 1)/(K - T[rt].k);
if(x > d[num[mid]]){
swap(T[rt].b,B);swap(T[rt].k,K);
update(rt<<1|1,mid+1,r,K,B);
}else update(rt<<1,l,mid,K,B);
}
if(l < r) T[rt].minn = min(T[rt<<1].minn,T[rt<<1|1].minn);
if(T[rt].lazy) T[rt].minn = min(T[rt].minn,
min(T[rt].k*d[num[l]],T[rt].k*d[num[r]])+T[rt].b);
}
void ins(ll rt,ll l,ll r){
if(L <= l && r <= R){
update(rt,l,r,K,B);return;
}
ll mid = l+r >> 1;
if(L <= mid) ins(rt<<1,l,mid);
if(R > mid) ins(rt<<1|1,mid+1,r);
T[rt].minn = min(T[rt<<1].minn,T[rt<<1|1].minn);
if(T[rt].lazy) T[rt].minn = min(T[rt].minn,
min(T[rt].k*d[num[l]],T[rt].k*d[num[r]])+T[rt].b);
}
inline void ins(ll l,ll r){
if(l > r) swap(l,r);
L=l;R=r;ins(1,1,n);
}
inline ll lca(ll u,ll 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;
}
inline void insert(ll u,ll v,ll a,ll b){
ll rt = lca(u,v);
K = -a;B = b+a*d[u];
while(top[u] != top[rt]){
ins(dfn[top[u]],dfn[u]);
u = fa[top[u]];
}ins(dfn[rt],dfn[u]);
K = a;B -= (d[rt]<<1)*a;
while(top[v] != top[rt]){
ins(dfn[top[v]],dfn[v]);
v = fa[top[v]];
}ins(dfn[rt],dfn[v]);
}
inline ll query_all(ll u,ll v){
ll ret = inf;
while(top[u] != top[v]){
if(dep[top[u]] < dep[top[v]]) swap(u,v);
ret = min(ret,query(dfn[top[u]],dfn[u]));
u = fa[top[u]];
}if(dep[u] < dep[v]) swap(u,v);
ret = min(ret,query(dfn[v],dfn[u]));
return ret;
}
int main(){
ll m;read(n);read(m);
for(ll i=1,u,v;i<n;++i){ll d;
read(u);read(v);read(d);
add(u,v,d);add(v,u,d);
}dfs(1);dfs(1,1);
ll op,s,t;ll a,b;
while(m--){
read(op);read(s);read(t);
if(op == 1){
read(a);read(b);
insert(s,t,a,b);
}else{
printf("%lld\n",query_all(s,t));
}
}
getchar();getchar();
return 0;
}

我能说我从昨天下午调到了今天上午,调了6个小时吗?

bzoj 4515: 游戏 树链剖分+线段树的更多相关文章

  1. BZOJ2819Nim——树链剖分+线段树+Nim游戏

    题目描述 著名游戏设计师vfleaking,最近迷上了Nim.普通的Nim游戏为:两个人进行游戏,N堆石子,每回合可以取其中某一堆的任意多个,可以取完,但不可以不取.谁不能取谁输.这个游戏是有必胜策略 ...

  2. BZOJ.4034 [HAOI2015]树上操作 ( 点权树链剖分 线段树 )

    BZOJ.4034 [HAOI2015]树上操作 ( 点权树链剖分 线段树 ) 题意分析 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三种: 操作 1 :把某个节点 ...

  3. BZOJ.1036 [ZJOI2008]树的统计Count ( 点权树链剖分 线段树维护和与最值)

    BZOJ.1036 [ZJOI2008]树的统计Count (树链剖分 线段树维护和与最值) 题意分析 (题目图片来自于 这里) 第一道树链剖分的题目,谈一下自己的理解. 树链剖分能解决的问题是,题目 ...

  4. BZOJ 3672[NOI2014]购票(树链剖分+线段树维护凸包+斜率优化) + BZOJ 2402 陶陶的难题II (树链剖分+线段树维护凸包+分数规划+斜率优化)

    前言 刚开始看着两道题感觉头皮发麻,后来看看题解,发现挺好理解,只是代码有点长. BZOJ 3672[NOI2014]购票 中文题面,题意略: BZOJ 3672[NOI2014]购票 设f(i)f( ...

  5. bzoj 4196 [Noi2015]软件包管理器 (树链剖分+线段树)

    4196: [Noi2015]软件包管理器 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 2852  Solved: 1668[Submit][Sta ...

  6. bzoj 2157: 旅游【树链剖分+线段树】

    裸的树链剖分+线段树 但是要注意一个地方--我WA了好几次才发现取完相反数之后max值和min值是要交换的-- #include<iostream> #include<cstdio& ...

  7. BZOJ 3589 动态树 (树链剖分+线段树)

    前言 众所周知,90%90\%90%的题目与解法毫无关系. 题意 有一棵有根树,两种操作.一种是子树内每一个点的权值加上一个同一个数,另一种是查询多条路径的并的点权之和. 分析 很容易看出是树链剖分+ ...

  8. 【BZOJ-2325】道馆之战 树链剖分 + 线段树

    2325: [ZJOI2011]道馆之战 Time Limit: 40 Sec  Memory Limit: 256 MBSubmit: 1153  Solved: 421[Submit][Statu ...

  9. 【BZOJ2243】[SDOI2011]染色 树链剖分+线段树

    [BZOJ2243][SDOI2011]染色 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的 ...

  10. BZOJ2243 (树链剖分+线段树)

    Problem 染色(BZOJ2243) 题目大意 给定一颗树,每个节点上有一种颜色. 要求支持两种操作: 操作1:将a->b上所有点染成一种颜色. 操作2:询问a->b上的颜色段数量. ...

随机推荐

  1. 兔子--改动Android Studio的快捷键,改动成eclipse的快捷键

    仅仅须要2步 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMzQyNTUyNw==/font/5a6L5L2T/fontsize/400/fill ...

  2. Bootstrap学习速查表(三) 表单

    表单中常见的元素主要包括:文本输入框.下拉选择框.单选按钮.复选按钮.文本域和按钮等. 一.基础表单 1.初始化:对于基础表单,Bootstrap并未对其做太多的定制性效果设计,仅仅对表单内的fiel ...

  3. 说说我的web前端之路,分享些前端的好书(转)

    WEB前端研发工程师,在国内算是一个朝阳职业,这个领域没有学校的正规教育,大多数人都是靠自己自学成才.本文主要介绍自己从事web开发以来(从大二至今)看过的书籍和自己的成长过程,目的是给想了解Java ...

  4. zeroMQ研究(转)

    偶尔一个机会,了解了下zeroMQ消息队列. 1  ZeroMQ概述 ZeroMQ是一种基于消息队列的多线程网络库,其对套接字类型.连接处理.帧.甚至路由的底层细节进行抽象,提供跨越多种传输协议的套接 ...

  5. 查看并修改Linux主机名命令hostname

    查看主机名 hostname可以查看主机名 export也可以查看 修改主机名 echo new-hostname > /proc/sys/kernel/hostname (系统启动时,从此文件 ...

  6. tao.opengl+C#绘制三维模型

    一.tao.Opengl技术简介 Opengl是一种C风格的图形库,即opengl中没有类和对象,只有大量的函数.Opengl在内部就是一个状态机,利用不同的函数来修改opengl状态机的状态,以达到 ...

  7. YII框架学习(二)

    YII框架的增删改查 例:一个新闻表的增删改查: (1)首先使用gii工具生成控制器和模型 (2)控制器 <?php class NewsController extends Controlle ...

  8. 【Android开发-5】界面装修,五大布局你选谁

    前言:假设要开一家店,门店装修是非常重要的事情.有钱都请专门的建筑设计公司来设计装修,没钱的仅仅能自己瞎折腾.好不好看全凭自己的感觉.像Android开发.在移动端大家看到的界面视觉不咋滴,一般连打开 ...

  9. python 基础 3.1 打开文件 a a+ r+ w+ 详解

      一.python 访问文件   1.在python中要访问文件,首先要打开文件,也就是open ---open   r:  只读   w:  只写 ,文件已存在则清空,不存在则创建   a:追加 ...

  10. activemq 搭建--集群

      linux activmemq 集群安装,配置和高可用测试       从 ActiveMQ 5.9 开始,ActiveMQ 的集群实现方式取消了传统的Master-Slave 方式,增加了基于Z ...