【BZOJ-4515】游戏 李超线段树 + 树链剖分 + 半平面交
4515: [Sdoi2016]游戏
Time Limit: 40 Sec Memory Limit: 256 MB
Submit:
304 Solved: 129
[Submit][Status][Discuss]
Description
的路径。
Input
Output
每当 Bob 进行操作,输出一行一个数,表示他能够选择的最小的数字
Sample Input
1 2 10
2 3 20
2 1 3
1
2 3 5 6
2 2 3
1 2 3 -5 -6
2 2 3
Sample Output
6
-106
HINT
n≤100000,m≤100000,∣a∣≤10000,0<=w,|b|<=10^9
Source
Solution
仍旧是李超线段树维护半平面交,唯一不同的是这里有了一个距离的定义
只需要在比较的时候带入端点和终点的距离即可,至于李超线段树,此处安利一个非常好的文章:戳这里
Code
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
long long read()
{
long long x=,f=; char ch=getchar();
while (ch<'' || ch>'') {if (ch=='-')f=-; ch=getchar();}
while (ch>='' && ch<='') {x=x*+ch-''; ch=getchar();}
return x*f;
}
#define maxn 100100
struct EdgeNode{int next,to;long long len;}edge[maxn<<];
int head[maxn],cnt;
void add(int u,int v,long long w)
{
cnt++;edge[cnt].to=v;edge[cnt].next=head[u];head[u]=cnt;edge[cnt].len=w;
}
void insert(int u,int v,long long w) {add(u,v,w); add(v,u,w);}
int n,m;
//--------------------------------------------------------------------------------------------------------
int pl[maxn],sz,pr[maxn],size[maxn],deep[maxn],son[maxn],top[maxn],fa[maxn];long long dis[maxn],pre[maxn];
void dfs_1(int x)
{
size[x]=;
for (int i=head[x]; i; i=edge[i].next)
if (edge[i].to!=fa[x])
{
fa[edge[i].to]=x;
deep[edge[i].to]=deep[x]+;
dis[edge[i].to]=dis[x]+edge[i].len;
dfs_1(edge[i].to);
if (size[son[x]]<size[edge[i].to]) son[x]=edge[i].to;
size[x]+=size[edge[i].to];
}
}
void dfs_2(int x,int chain)
{
pl[x]=++sz; pre[sz]=dis[x]; top[x]=chain;
if (son[x]) dfs_2(son[x],chain);
for (int i=head[x]; i; i=edge[i].next)
if (edge[i].to!=fa[x] && edge[i].to!=son[x])
dfs_2(edge[i].to,edge[i].to);
pr[x]=sz;
}
int LCA(int x,int y)
{
while (top[x]!=top[y])
{
if (deep[top[x]]<deep[top[y]]) swap(x,y);
x=fa[top[x]];
}
if (deep[x]>deep[y]) swap(x,y);
return x;
}
//--------------------------------------------------------------------------------------------------------
long long f(long long x,long long k,long long b) {return k*x+b;}
struct TreeNode{long long a,b,minn;}tree[maxn<<];
#define inf 123456789123456789LL
void Build(int now,int l,int r)
{
tree[now].a=; tree[now].b=tree[now].minn=inf;
if (l==r) return;
int mid=(l+r)>>;
Build(now<<,l,mid); Build(now<<|,mid+,r);
}
long long Query(int now,int l,int r,int L,int R)
{
long long re=min(f(pre[L],tree[now].a,tree[now].b),f(pre[R],tree[now].a,tree[now].b));
if (l==L && r==R) return min(re,tree[now].minn);
int mid=(l+r)>>;
if (R<=mid) return min(re,Query(now<<,l,mid,L,R));
else if (L>mid) return min(re,Query(now<<|,mid+,r,L,R));
else return min(re,min(Query(now<<,l,mid,L,mid),Query(now<<|,mid+,r,mid+,R)));
}
void Change(int now,int l,int r,long long a,long long b)
{
int mid=(l+r)>>,fl,fr,fm;
fl=(f(pre[l],tree[now].a,tree[now].b)>f(pre[l],a,b));
fr=(f(pre[r],tree[now].a,tree[now].b)>f(pre[r],a,b));
fm=(f(pre[mid],tree[now].a,tree[now].b)>f(pre[mid],a,b));
if (fl&fr&fm)
{
tree[now].a=a;tree[now].b=b;tree[now].minn=min(tree[now].minn,min(f(pre[l],a,b),f(pre[r],a,b)));
return;
}
if (!(fl|fr|fm)) return;
if (fm)
{
if (fr) Change(now<<,l,mid,tree[now].a,tree[now].b);
else Change(now<<|,mid+,r,tree[now].a,tree[now].b);
tree[now].a=a;tree[now].b=b;tree[now].minn=min(tree[now].minn,min(f(pre[l],a,b),f(pre[r],a,b)));
}
if (!fm)
if (!fr) Change(now<<,l,mid,a,b);
else Change(now<<|,mid+,r,a,b);
tree[now].minn=min(tree[now].minn,min(tree[now<<].minn,tree[now<<|].minn));
}
void change(int now,int l,int r,int L,int R,long long a,long long b)
{
if (L<=l && R>=r) {Change(now,l,r,a,b); return;}
int mid=(l+r)>>;
if (L<=mid) change(now<<,l,mid,L,R,a,b);
if (R>mid) change(now<<|,mid+,r,L,R,a,b);
tree[now].minn=min(tree[now].minn,min(tree[now<<].minn,tree[now<<|].minn));
}
//--------------------------------------------------------------------------------------------------------
void Solve_Insert(int s,int t,long long a,long long b)
{
int lca=LCA(s,t); int x=s,y=t;
while (top[x]!=top[lca])
{
change(,,n,pl[top[x]],pl[x],-a,a*dis[s]+b);
x=fa[top[x]];
}
change(,,n,pl[lca],pl[x],-a,a*dis[s]+b);
while (top[y]!=top[lca])
{
change(,,n,pl[top[y]],pl[y],a,dis[s]*a-dis[lca]**a+b);
y=fa[top[y]];
}
if (y!=lca) change(,,n,pl[lca]+,pl[y],a,dis[s]*a-dis[lca]**a+b);
}
long long Solve_Query(int s,int t)
{
int x=s,y=t; long long re=inf;
while (top[x]!=top[y])
{
if (deep[top[x]]<deep[top[y]]) swap(x,y);
re=min(Query(,,n,pl[top[x]],pl[x]),re);
x=fa[top[x]];
}
if (deep[x]>deep[y]) swap(x,y);
re=min(Query(,,n,pl[x],pl[y]),re);
return re;
}
//--------------------------------------------------------------------------------------------------------
int main()
{
// freopen("menci_game.in","r",stdin);
// freopen("menci_game.out","w",stdout);
n=read();m=read(); long long w;
for (int u,v,i=; i<=n-; i++)
u=read(),v=read(),w=(long long)read(),insert(u,v,w);
dfs_1(); dfs_2(,); Build(,,n);
while (m--)
{
int opt=read();
if (opt==)
{
int s=read(),t=read();long long a=read(),b=read();
Solve_Insert(s,t,a,b);
}
if (opt==)
{
int s=read(),t=read();
printf("%lld\n",Solve_Query(s,t));
}
}
return ;
}
考场上,看到这个题,这不是裸树链剖分么,线段树维护半平面交,裸李超线段树啊,Clrs的模版上有哎,虽然我没写过,但是我知道大体的方法啊,然后开始码,码到最后连暴力都没打,然后愉快滚粗TAT/...
【BZOJ-4515】游戏 李超线段树 + 树链剖分 + 半平面交的更多相关文章
- 【xsy3423】党² 线段树+李超线段树or动态半平面交
本来并不打算出原创题的,此题集CF542A和sk的灵感而成,算个半原创吧. 题目大意: 给定有$n$个元素的集合$P$,其中第$i$个元素中包含$L_i,R_i,V_i$三个值. 给定另一个有$n$个 ...
- bzoj 4445 小凸想跑步 - 半平面交
题目传送门 vjudge的快速通道 bzoj的快速通道 题目大意 问在一个凸多边形内找一个点,连接这个点和所有顶点,使得与0号顶点,1号顶点构成的三角形是最小的概率. 假设点的位置是$(x, y)$, ...
- BZOJ 4445 [Scoi2015]小凸想跑步:半平面交
传送门 题意 小凸晚上喜欢到操场跑步,今天他跑完两圈之后,他玩起了这样一个游戏. 操场是个凸 $ n $ 边形,$ n $ 个顶点 $ P_i $ 按照逆时针从 $ 0 $ 至 $ n-1 $ 编号. ...
- BZOJ.3938.Robot(李超线段树)
BZOJ UOJ 以时间\(t\)为横坐标,位置\(p\)为纵坐标建坐标系,那每个机器人就是一条\(0\sim INF\)的折线. 用李超线段树维护最大最小值.对于折线分成若干条线段依次插入即可. 最 ...
- 洛谷P4069 [SDOI2016]游戏(李超线段树)
题意 题目链接 Sol 这题细节好多啊qwq..稍不留神写出一个小bug就要调1h+.. 思路就不多说了,把询问区间拆成两段就是李超线段树板子题了. 关于dis的问题可以直接维护. // luogu- ...
- 线段树&数链剖分
傻逼线段树,傻逼数剖 线段树 定义: 线段树是一种二叉搜索树,与区间树相似,它将一个区间划分成一些单元区间,每个单元区间对应线段树中的一个叶结点. 使用线段树可以快速的查找某一个节点在若干条线段中出现 ...
- bzoj 4515: 游戏 树链剖分+线段树
题目大意: http://www.lydsy.com/JudgeOnline/problem.php?id=4515 题解: 先让我%一发lych大佬点我去看dalao的题解 讲的很详细. 这里纠正一 ...
- bzoj 2732 射箭 半平面交
2732: [HNOI2012]射箭 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 2531 Solved: 848[Submit][Status] ...
- BZOJ 1038 ZJOI2008 瞭望塔 半平面交
题目大意及模拟退火题解:见 http://blog.csdn.net/popoqqq/article/details/39340759 这次用半平面交写了一遍--求出半平面交之后.枚举原图和半平面交的 ...
随机推荐
- Hibernate总结2 API和配置文件
1,Configuration 配置 获取config配置文件的方法 Configuration cfg = new Configuration(); cfg.下面的方法 configure() co ...
- usb驱动开发13之设备生命线
上一节勉勉强强把struct urb这个中心给说完,接着看那三个基本点. 第一个基本点,usb_alloc_urb函数,创建urb的专用函数,为一个urb申请内存并做初始化,在drviers/usb/ ...
- Eclipse使用Maven构建web项目
1.创建Maven项目: 点击“File”菜单,或者通过工具栏的“New”创建Project,如下图所示: 选择Maven->Maven Project,弹出向导对话框,如下图所示: 选中Cre ...
- c++虚函数注意事项
>在基类方法声明中使用关键字virtual,可以使该方法在基类及所有的派生类中是虚的 >如果使用指向对象的引用或指针来调用虚方法,程序将使用对象类型定义的方法,而不使用为引用或指针类型定义 ...
- linux基础-第十六单元 yum管理RPM包
第十六单元 yum管理RPM包 yum的功能 本地yum配置 光盘挂载和镜像挂载 本地yum配置 网络yum配置 网络yum配置 Yum命令的使用 使用yum安装软件 使用yum删除软件 安装组件 删 ...
- VS2013 无法在Web服务器上启动调试。IIS未列出与打开的URL匹配的网站。
出现这个问题的原因是:没有用管理员权限运行VS2013. 本来遇到这个问题的时候,不知道什么原因.后来附加到进程调试的时候,提示要以管理员身份运行.才知道啥原因.
- 2016年GitHub 排名前 100 的安卓、iOS项目简介(收藏)
排名完全是根据 GitHub 搜索 Java 语言选择 (Best Match) 得到的结果, 然后过滤了跟 Android 不相关的项目, 所以排名并不具备任何官方效力, 仅供参考学习, 方便初学者 ...
- Android-动画简介
Android中动画分为3种: ween Animation:通过对场景里的对象不断做图像变换(平移.缩放.旋转)产生动画效果,即是一种渐变动画: 也称View动画:也叫渐变动画,针对View的动画, ...
- 本机ubuntu链接阿里云服务器(也是ubuntu)
首先在本机安装ssh工具,并修改配置文件(参考:http://www.cnblogs.com/herd/p/5009067.html) 第一步:ssh 100.121.156.32(即:服务器的ip地 ...
- 【BZOJ 2820】YY的GCD
线性筛积性函数$g(x)$,具体看Yveh的题解: http://sr16.com:8081/%e3%80%90bzoj2820%e3%80%91yy%e7%9a%84gcd/ #include< ...