首先有个暴力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的更多相关文章

  1. ILJMALL project过程中遇到Fragment嵌套问题:IllegalArgumentException: Binary XML file line #23: Duplicate id

    出现场景:当点击"分类"再返回"首页"时,发生error退出   BUG描述:Caused by: java.lang.IllegalArgumentExcep ...

  2. 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 ...

  3. 关于xml加载提示: Error on line 1 of document : 前言中不允许有内容

    我是在java中做的相关测试, 首先粘贴下报错: 读取xml配置文件:xmls\property.xml org.dom4j.DocumentException: Error on line 1 of ...

  4. Eclipse "Unable to install breakpoint due to missing line number attributes..."

    Eclipse 无法找到 该 断点,原因是编译时,字节码改变了,导致eclipse无法读取对应的行了 1.ANT编译的class Eclipse不认,因为eclipse也会编译class.怎么让它们统 ...

  5. Linix登录报"/etc/profile: line 11: syntax error near unexpected token `$'{\r''"

    同事反馈他在一测试服务器(CentOS Linux release 7.2.1511)上修改了/etc/profile文件后,使用source命令不能生效,让我帮忙看看,结果使用SecureCRT一登 ...

  6. [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 ...

  7. [LeetCode] Tenth Line 第十行

    How would you print just the 10th line of a file? For example, assume that file.txt has the followin ...

  8. [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. ...

  9. "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 ...

随机推荐

  1. C - A Plug for UNIX (又是建图坑)

    题目链接:https://cn.vjudge.net/contest/68128#problem/C 没理解好题意真的麻烦,一上午就这么过去了..... 具体思路:按照 源点 ->插座-> ...

  2. Dream------scala--类的属性和对象私有字段实战详解

    Scala类的属性和对象私有字段实战详解 一.类的属性 scala类的属性跟java有比较大的不同,需要注意的是对象的私有(private)字段 1.私有字段:字段必须初始化(当然即使不是私有字段也要 ...

  3. oracle建表,设置主键,修改属性等

    --建表 create table book( book_id number(10), book_name varchar2(20), book_price number(10,2), book_au ...

  4. Css中实现一个盒子固定宽度,另一个盒子宽度自适应的方法

    Css中实现一个盒子固定宽度,另一个盒子宽度自适应的方法 网上方法很多,个人认为以下两种思想是最为常用的. 一种是让第一个盒子脱离文档流,第二个盒子离左边有一定距离. 第二种方法是使用flex布局,不 ...

  5. 【codeforces】【比赛题解】#872 CF Round #440 (Div.2)

    链接. [A]寻找漂亮数字 题意: 给定了两列非零数字.我们说一个数是漂亮的,当它的十进制表达中有至少一个数从数列一中取出,至少有一个数从数列二中取出.最小的漂亮数字是多少? 输入: 第一行两个数\( ...

  6. 连续的if语句

    use_relu=0 use_tanh=2 a = 2 if use_relu else (1 if use_tanh else 0)#如果use_relu不等于0,则a等于2:如果use_relu等 ...

  7. JDK1.8源码ArrayList

    线程不安全的,如果要想线程安全必须在创建的时候就采用线程安全的方式创建: List list = Collections.synchronizedList(new ArrayList(...)); 引 ...

  8. C# 日文网址转punnycode

    Uri uri = new Uri(url); IdnMapping idn = new IdnMapping();url= url.Replace(uri.Host, idn.GetAscii(ur ...

  9. [转载]如何在C++03中模拟C++11的右值引用std::move特性

    本文摘自: http://adamcavendish.is-programmer.com/posts/38190.htm 引言 众所周知,C++11 的新特性中有一个非常重要的特性,那就是 rvalu ...

  10. Mac ssh

    mac的终端默认在打开一个新的tab/window的时候需要重新输入ssh的密码, 很不方便.本文完成在mac中设置,实现secureCRT/xshell里的克隆会话功能, 即新开一个terminal ...