[SDOI2016]游戏 树剖+李超树
链接
https://www.luogu.org/problemnew/show/P4069
思路
树剖+超哥线段树
我已经自毙了,自闭了!!!!
update
上次抄了没认真看,这次考试又自毙了
是一个细节的处理上一次没处理
代码
#include <bits/stdc++.h>
#define ll long long
#define ls rt<<1
#define rs rt<<1|1
using namespace std;
const ll inf=123456789123456789LL;
const ll N=5e5+7;
ll read() {
ll x=0,f=1;char s=getchar();
for(;s>'9'||s<'0';s=getchar()) if(s=='-') f=-1;
for(;s>='0'&&s<='9';s=getchar()) x=x*10+s-'0';
return x*f;
}
ll n,m;
struct edge {
ll v,nxt,q;
}e[N<<1];
ll head[N<<1],tot;
void add(ll u,ll v,ll q) {
e[++tot].v=v;
e[tot].q=q;
e[tot].nxt=head[u];
head[u]=tot;
}
ll fa[N],dep[N],son[N],siz[N];
ll dis[N];
void dfs1(ll u,ll f) {
dep[u]=dep[f]+1;
siz[u]=1;
fa[u]=f;
for(ll i=head[u];i;i=e[i].nxt) {
ll v=e[i].v;
if(v==f) continue;
dis[v]=dis[u]+(ll)e[i].q;
dfs1(v,u);
siz[u]+=siz[v];
if(siz[son[u]]<siz[v]) son[u]=v;
}
}
ll idx[N],top[N],js;
ll xxx[N];
void dfs2(ll u,ll topf) {
idx[u]=++js;
xxx[js]=u;
top[u]=topf;
if(!son[u]) return;
dfs2(son[u],topf);
for(ll i=head[u];i;i=e[i].nxt) {
ll v=e[i].v;
if(!idx[v]) dfs2(v,v);
}
}
struct node {
ll l,r;
ll a,b,mi;
}tr[N<<2];
void build(ll l,ll r,ll rt) {
tr[rt].l=l,tr[rt].r=r;
tr[rt].mi=tr[rt].b=inf;
if(l==r) return;
ll mid=(l+r)>>1;
build(l,mid,ls);
build(mid+1,r,rs);
}
ll f(ll a,ll b,ll x) {
return a*dis[xxx[x]]+b;
}
#define f_l f(tr[rt].a,tr[rt].b,tr[rt].l)
#define f_r f(tr[rt].a,tr[rt].b,tr[rt].r)
void pushup(ll rt) {
tr[rt].mi=min(tr[rt].mi,min(tr[ls].mi,tr[rs].mi));
tr[rt].mi=min(tr[rt].mi,min(f_l,f_r));
}
void modify(ll L,ll R,ll a,ll b,ll rt) {
if(L<=tr[rt].l&&tr[rt].r<=R) {
if(f_l<=f(a,b,tr[rt].l)&&f_r<=f(a,b,tr[rt].r)) return;
if(f_l>f(a,b,tr[rt].l)&&f_r>f(a,b,tr[rt].r)) {
tr[rt].a=a;
tr[rt].b=b;
tr[rt].mi=min(tr[rt].mi,min(f_l,f_r));
return;
}
ll mid=(tr[rt].l+tr[rt].r)>>1;
if(tr[rt].a<=a) {
if(f(tr[rt].a,tr[rt].b,mid)>=f(a,b,mid)) {
swap(tr[rt].a,a);
swap(tr[rt].b,b);
modify(L,R,a,b,rs);
} else modify(L,R,a,b,ls);
} else {
if(f(tr[rt].a,tr[rt].b,mid)>=f(a,b,mid)) {
swap(tr[rt].a,a);
swap(tr[rt].b,b);
modify(L,R,a,b,ls);
} else modify(L,R,a,b,rs);
}
tr[rt].mi= min(min(tr[ls].mi, tr[rs].mi), min(f_l,f_r));
// pushup(rt);
return;
}
ll mid=(tr[rt].l+tr[rt].r)>>1;
if(L<=mid) modify(L,R,a,b,ls);
if(R>mid) modify(L,R,a,b,rs);
pushup(rt);
}
ll query(ll L,ll R,ll rt) {
if(L<=tr[rt].l&&tr[rt].r<=R) {
return tr[rt].mi;
}
ll mid=(tr[rt].l+tr[rt].r)>>1;
ll ans=inf;
ans=min(ans,min(f(tr[rt].a,tr[rt].b,max(L,tr[rt].l)),f(tr[rt].a,tr[rt].b,min(tr[rt].r,R))));
if(L<=mid) ans=min(ans,query(L,R,ls));
if(R>mid) ans=min(ans,query(L,R,rs));
return ans;
}
ll lca(ll x,ll y) {
while(top[x]!=top[y]) {
if(dep[top[x]] < dep[top[y]]) swap(x,y);
x=fa[top[x]];
}
if(dep[x]>dep[y]) swap(x,y);
return x;
}
void C(ll x,ll y,ll a,ll b) {
while(top[x]!=top[y]) {
if(dep[top[x]] < dep[top[y]]) swap(x,y);
modify(idx[top[x]],idx[x],a,b,1);
x=fa[top[x]];
}
if(dep[x]>dep[y]) swap(x,y);
modify(idx[x],idx[y],a,b,1);
}
void Q(ll x,ll y) {
ll ans=inf;
while(top[x]!=top[y]) {
if(dep[top[x]] < dep[top[y]]) swap(x,y);
ans=min(ans,query(idx[top[x]],idx[x],1));
x=fa[top[x]];
}
if(dep[x]>dep[y]) swap(x,y);
ans=min(ans,query(idx[x],idx[y],1));
printf("%lld\n",ans);
}
int main() {
n=read(),m=read();
for(ll i=1;i<n;++i) {
ll x=read(),y=read(),z=read();
add(x,y,z);
add(y,x,z);
}
dfs1(1,0);
dfs2(1,1);
build(1,n,1);
while(m--) {
ll opt=read();
if(opt==1) {
ll s=read(),t=read();
ll A=read(),B=read();
ll dsr=lca(s,t);
C(s,dsr,(ll)-A,1LL*dis[s]*A+B);
C(dsr,t,(ll)A,1LL*dis[s]*A-2LL*A*dis[dsr]+B);
} else {
ll s=read(),t=read();
Q(s,t);
}
}
return 0;
}
[SDOI2016]游戏 树剖+李超树的更多相关文章
- [SDOI2016]游戏(树剖+李超树)
趁着我把李超树忘个一干二净的时候来复习一下吧,毕竟马上NOI了. 题解:看着那个dis就很不爽,直接把它转换成深度问题,然后一条直线x->y,假设其lca为z,可以拆分成x->z和z-&g ...
- BZOJ_2238_Mst_树剖+线段树
BZOJ_2238_Mst_树剖+线段树 Description 给出一个N个点M条边的无向带权图,以及Q个询问,每次询问在图中删掉一条边后图的最小生成树.(各询问间独立,每次询问不对之后的询问产生影 ...
- BZOJ_2588_Spoj 10628. Count on a tree_树剖+主席树
BZOJ_2588_Spoj 10628. Count on a tree_树剖+主席树 题意: 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastan ...
- BZOJ_4551_[Tjoi2016&Heoi2016]树_树剖+线段树
BZOJ_4551_[Tjoi2016&Heoi2016]树_树剖+线段树 Description 在2016年,佳媛姐姐刚刚学习了树,非常开心.现在他想解决这样一个问题:给定一颗有根树(根为 ...
- BZOJ_2157_旅游_树剖+线段树
BZOJ_2157_旅游_树剖+线段树 Description Ray 乐忠于旅游,这次他来到了T 城.T 城是一个水上城市,一共有 N 个景点,有些景点之间会用一座桥连接.为了方便游客到达每个景点但 ...
- 【BZOJ5210】最大连通子块和 树剖线段树+动态DP
[BZOJ5210]最大连通子块和 Description 给出一棵n个点.以1为根的有根树,点有点权.要求支持如下两种操作: M x y:将点x的点权改为y: Q x:求以x为根的子树的最大连通子块 ...
- [LNOI2014]LCA(树剖+线段树)
\(\%\%\% Fading\) 此题是他第一道黑题(我的第一道黑题是蒲公英) 一直不敢开,后来发现是差分一下,将询问离线,树剖+线段树维护即可 \(Code\ Below:\) #include ...
- [CF1007D]Ants[2-SAT+树剖+线段树优化建图]
题意 我们用路径 \((u, v)\) 表示一棵树上从结点 \(u\) 到结点 \(v\) 的最短路径. 给定一棵由 \(n\) 个结点构成的树.你需要用 \(m\) 种不同的颜色为这棵树的树边染色, ...
- 2018.08.30 NOIP模拟 graph(dfs序/树剖+线段树)
[描述] 给你一个图,一共有 N 个点,2*N-2 条有向边. 边目录按两部分给出 1. 开始的 n-1 条边描述了一颗以 1 号点为根的生成树,即每个点都可以由 1 号点 到达. 2. 接下来的 N ...
随机推荐
- 输出列表为字符串,并在最后一个值前加上and 4.10.1
逗号代码: def test4(lis): str1='' for i in range(len(lis)-1): str1+=(str(val[i])+', ') str1+=('and '+str ...
- C# 调整控件的Z顺序
当窗口或者容器控件中的控件在布局过程中发生重叠的时候,会出现层次性.Z顺序较大的控件会遮挡Z顺序较小的控件,放在顶层的控件会挡住放在底层的控件. 1.编辑一个这样的窗口(使用Label控件) 2.添加 ...
- 排名函数——ROW_NUMBER()、RANK()、DENSE_RANK()和NTILE(n)
ROW_NUMBER()函数:行号,根据作为参数传递给这个函数的ORDER BY子句的值,返回一个不断递增的整数值.如果ROW_NUMBER的ORDER BY的值和结果集中的顺序相匹配,返回值将是递增 ...
- 常用正则表达式爬取网页信息及HTML分析总结
Python爬取网页信息时,经常使用的正则表达式及方法. 1.获取<tr></tr>标签之间内容 2.获取<a href..></a>超链接之间内容 3 ...
- 记账本微信小程序开发三
一.制作登陆界面: 更改全局配置,改颜色,名称: 界面 格式 登录界面 二.页面的跳转 按钮的设置 注册事件 结果
- Linux下输出 excel文件
Linux下输出 excel文件 今日提供给产品需求,需excel文件,故总结要点如下: 1.默认间隔是space_20 2.修改为TAB \t _09 awk ' BEGIN { OFS=&quo ...
- 前端框架VUE----指令
一.什么是VUE? 它是构建用户界面的JavaScript框架(让它自动生成js,css,html等) 二.怎么使用VUE? 1.引入vue.js 2.展示HTML <div id=" ...
- jquery easyui datagrid 空白条处理 自适应宽高 格式化函数formmater 初始化时会报错 cannot read property 'width'||'length' of null|undefined
1---表格定义好之后右侧可能会有一个空白条 这个空白条是留给滚动条的,当表格中的一页的数据在页面中不能全显示时会自动出现滚动条,网上有很多事要改源码才可以修改这个,但是当项目中多处用到时,有的需要滚 ...
- 使用v-bind处理class与style
普通的css引入: 变量引入: 通过定义一个变量fontColor来通过v-bind来进行绑定在h3z的class中 <!--变量引入--> <h3 :class="fon ...
- P3924 康娜的线段树(期望)
P3924 康娜的线段树 看起来$O(nlogn)$可过其实由于巨大常数是无法通过的 $O(nlogn)$:70pts 我们手玩样例发现 线段树上某个节点的期望值$f[o]=(f[lc]+f[rc]) ...