[UOJ430]line
首先有个暴力DP,设$s_i=\sum\limits_{j\geq i}w_j$,有$f_i=\min\limits_{l_i\lt j\leq i}f_{j-1}+s_{i+1}\max\{t_{j\cdots i}\}$
想用斜率优化,但是式中的max会随$i$改变而改变
考虑把单调栈的弹栈序列建成一棵树,每个点$x$存的直线为$y=t_xx+\min\{f_{fa_x+1\cdots x}\}$,这样一个点要查的直线就是到根路径的一条链,$l_i$的限制在最后一小段查$f$的区间最小值即可
这棵树有很好的性质,从根往下走的$t_x$是不升的,我们要查的$s_{i+1}$是递减的,所以可以树剖+线段树维护凸壳,边插入边维护即可
总时间复杂度$O(n\log^2n)$,感觉把单调栈建成树这一步非常厉害
#include<stdio.h> #include<vector> using namespace std; typedef long long ll; typedef double du; const ll inf=1e18; void fmin(ll&a,ll b){ if(b<a)a=b; } int l[100010],t[100010],w[100010],n; ll s[100010]; int st[100010],tp; int h[100010],nex[100010],to[100010],M; void add(int a,int b){ M++; to[M]=b; nex[M]=h[a]; h[a]=M; } int fa[100010],siz[100010],son[100010]; void dfs(int x){ int i,k=-1; siz[x]=1; for(i=h[x];i;i=nex[i]){ fa[to[i]]=x; dfs(to[i]); siz[x]+=siz[to[i]]; if(k==-1||siz[to[i]]>siz[k])k=to[i]; } son[x]=k; } int bl[100010],pos[100010],rp[100010]; void dfs(int x,int chain){ bl[x]=chain; pos[x]=++M; rp[M]=x; if(~son[x])dfs(son[x],chain); for(int i=h[x];i;i=nex[i]){ if(to[i]!=son[x])dfs(to[i],to[i]); } } struct line{ ll k,b; line(ll k=0,ll b=0):k(k),b(b){} ll v(ll x){return k*x+b;} }; du its(line a,line b){ return(b.b-a.b)/(du)(a.k-b.k); } typedef vector<line> vl; vl g[400010]; #define ls g[g.size()-1] void push(vl&g,line v){ if(!g.empty()&&ls.k==v.k){ if(ls.b<=v.b)return; g.pop_back(); } while(g.size()>1&&its(ls,g[g.size()-2])>=its(ls,v))g.pop_back(); g.push_back(v); } void modify(int p,line v,int l,int r,int x){ push(g[x],v); if(l==r)return; int mid=(l+r)>>1; if(p<=mid) modify(p,v,l,mid,x<<1); else modify(p,v,mid+1,r,x<<1|1); } ll get(vl&g,ll v){ while(g.size()>1&&its(ls,g[g.size()-2])>=v)g.pop_back(); return ls.v(v); } ll query(int L,int R,ll v,int l,int r,int x){ if(L<=l&&r<=R)return get(g[x],v); int mid=(l+r)>>1; ll res=inf; if(L<=mid)fmin(res,query(L,R,v,l,mid,x<<1)); if(mid<R)fmin(res,query(L,R,v,mid+1,r,x<<1|1)); return res; } ll f[100010]; ll T[400010]; int N; void build(){ for(N=1;N<=n+1;N<<=1); for(int i=1;i<N<<1;i++)T[i]=inf; } void modify(int x,ll v){ T[x+=N]=v; for(x>>=1;x;x>>=1)T[x]=min(T[x<<1],T[x<<1|1]); } ll query(int s,int t){ ll res=inf; for(s+=N-1,t+=N+1;s^t^1;s>>=1,t>>=1){ if(~s&1)fmin(res,T[s^1]); if(t&1)fmin(res,T[t^1]); } return res; } void work(int x){ int u,l,r,mid; ll res; modify(x,f[x-1]); modify(pos[x],line(t[x],query(fa[x]+1,x)),1,M,1); res=inf; for(u=x;;){ if(::l[x]>fa[bl[u]]){ l=pos[bl[u]]; r=pos[u]; while(l<r){ mid=(l+r)>>1; if(rp[mid]>=::l[x]) r=mid; else l=mid+1; } if(pos[u]>l)fmin(res,query(l+1,pos[u],s[x+1],1,M,1)); u=rp[l]; break; }else{ fmin(res,query(pos[bl[u]],pos[u],s[x+1],1,M,1)); u=fa[bl[u]]; } } fmin(res,query(::l[x],u)+t[u]*s[x+1]); f[x]=res; } int main(){ int i; scanf("%d",&n); for(i=1;i<=n;i++){ scanf("%d%d%d",l+i,t+i,w+i); l[i]++; } for(i=n;i>0;i--)s[i]=s[i+1]+w[i]; for(i=1;i<=n;i++){ while(tp&&t[i]>t[st[tp]]){ add(st[tp-1],st[tp]); tp--; } st[++tp]=i; } for(i=1;i<=tp;i++)add(st[i-1],st[i]); dfs(0); M=0; dfs(0,0); fa[0]=-1; build(); for(i=1;i<=n;i++)work(i); printf("%lld",f[n]); }
[UOJ430]line的更多相关文章
- ILJMALL project过程中遇到Fragment嵌套问题:IllegalArgumentException: Binary XML file line #23: Duplicate id
出现场景:当点击"分类"再返回"首页"时,发生error退出 BUG描述:Caused by: java.lang.IllegalArgumentExcep ...
- Error on line -1 of document : Premature end of file. Nested exception: Premature end of file.
启动tomcat, 出现, ( 之前都是好好的... ) [lk ] ERROR [08-12 15:10:02] [main] org.springframework.web.context.Con ...
- 关于xml加载提示: Error on line 1 of document : 前言中不允许有内容
我是在java中做的相关测试, 首先粘贴下报错: 读取xml配置文件:xmls\property.xml org.dom4j.DocumentException: Error on line 1 of ...
- Eclipse "Unable to install breakpoint due to missing line number attributes..."
Eclipse 无法找到 该 断点,原因是编译时,字节码改变了,导致eclipse无法读取对应的行了 1.ANT编译的class Eclipse不认,因为eclipse也会编译class.怎么让它们统 ...
- Linix登录报"/etc/profile: line 11: syntax error near unexpected token `$'{\r''"
同事反馈他在一测试服务器(CentOS Linux release 7.2.1511)上修改了/etc/profile文件后,使用source命令不能生效,让我帮忙看看,结果使用SecureCRT一登 ...
- [LeetCode] Line Reflection 直线对称
Given n points on a 2D plane, find if there is such a line parallel to y-axis that reflect the given ...
- [LeetCode] Tenth Line 第十行
How would you print just the 10th line of a file? For example, assume that file.txt has the followin ...
- [LeetCode] Max Points on a Line 共线点个数
Given n points on a 2D plane, find the maximum number of points that lie on the same straight line. ...
- "Installation failed !" in GUI but not in CLI (/usr/bin/winusb: line 78: 18265 Terminated )
"Installation failed !" in GUI but not in CLI (/usr/bin/winusb: line 78: 18265 Terminated ...
随机推荐
- PCA主成分分析理解
一.理论概述 1)问题引出 先看如下几张图: 从上述图中可以看出,如果将3个图的数据点投影到x1轴上,图1的数据离散度最高,图3其次,图2最小.数据离散性越大,代表数据在所投影的维度上具有越高的区分度 ...
- sql____001
题目: create table my_001 (id int,value int); insert into my_001 values(1,10): insert into my_001 valu ...
- elasticsearch-head插件安装的一些坑!es6.5.4版本
折腾了一晚上,总算成功了!,大部分坑都记录了下来,版本升级太快真实个大坑,每个版本都不一样,学的心累!! 这坑太多了!主要就是以下几点最主要的: 因为我这里只使用hear安装,不使用哪个打包工具,所以 ...
- java 一个函数如何返回多个值
在开发过程中,经常会有这种情况,就是一个函数需要返回多个值,这是一个问题!! 网上这个问题的解决方法: 1.使用map返回值:这个方法问题是,你并不知道如何返回值的key是什么,只能通过doc或者通过 ...
- 使用DOS访问数据库详解
今天突发奇想,想是否可以用DOS命令来操作本地数据库或者连接其他外地数据库,网上搜了很多教程比较繁琐,自己想写一篇文章详细叙述一下,也为以后复习做点备份. 工具: 电脑 win7 64bit MySQ ...
- 缓存数据库-redis数据类型和操作(string)
Redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合) 一:String(字符串) string是redis ...
- java 闭包与回调
闭包(closure)是一个可调用的对象,它记录了一些信息,这些信息来自于创建它的作用域. 内部类是面向对象的闭包,因为它不仅包含外围类对象(创建内部类的作用域)的信息,还自动拥有一个指向此外围类对象 ...
- NFS服务简介
NFS服务简介 NFS是Network File System的缩写,即网络文件系统.NFS是由Sun开发并发展起来的一项用于在不同机器,不同操作系统之间通过网络互相分享各自的文件.NFS serve ...
- SQL数据是否存在(是否有数据)判断,表,存储过程是否存在
判断是否存在数据 if exists( select * from Hong_PageConfig where names='name' ) Begin print '1' End else Begi ...
- Centos 常用命令[持续积累中...]
CentOS常用到的查看系统命令 uname -a cat /etc/issue /sbin/ifconfig # 查看内核/操作系统/CPU信息 head -n 1 /etc/issue # 查看操 ...