首先将所有高度乘上10,设f[i]为将前i本书放入书架的最小高度,则

\[\begin{eqnarray*}
f[i]&=&\min(f[j-1]+first(j,i)+second(j,i)+W-(s[i]-s[j-1]))\\
&=&\min(f[j-1]+first(j,i)+second(j,i)+W-s[i]+s[j-1])\\
&=&\min(f[j-1]+first(j,i)+second(j,i)+s[j-1])+W-s[i]
\end{eqnarray*}\]

其中$1\leq j\leq i$且$s[i]-s[j-1]\leq W$。

设tmp[i][j]=f[j-1]+s[j-1]+first(j,i)+second(j,i),考虑用线段树维护tmp[i][j],如果当前要计算f[i],那么线段树的第j个叶子节点就表示tmp[i][j]。

为了高效维护first和second,先将所有书按高度排序,从大到小插入到set中。

假设现在插入的是第x本书,那么对于[pre(x)+1,x]内的i,first(i,x)均为a[x]。

对于[pre(pre(x))+1,pre(x)]内的i,以及[x,nxt(x)-1]内的j,second(i,j)均为a[x]。

对于[pre(x)+1,x]内的i,以及[nxt(x),nxt(nxt(x))-1]内的j,second(i,j)也均为a[x]。

于是在右端点的最小值处进行区间赋值操作即可。

时间复杂度$O(n\log n)$。

#include<cstdio>
#include<algorithm>
#include<set>
#define N 300010
using namespace std;
typedef long long ll;
int n,w,i,j,k,c[N],l[N],g[N],vl[N<<1],vr[N<<1],nxt[N<<1],ed;ll a[N],b[N],vw[N<<1],f;
set<int>T;set<int>::iterator it;
inline bool cmp(int x,int y){return a[x]<a[y];}
inline int get(){char c;while(!(((c=getchar())>='0')&&(c<='9')));int a=c-'0';while(((c=getchar())>='0')&&(c<='9'))(a*=10)+=c-'0';return a;}
inline void add(int x,int l,int r,ll w){vl[++ed]=l;vr[ed]=r;vw[ed]=w;nxt[ed]=g[x];g[x]=ed;}
struct node{ll v1,v2,vc,v,t1,t2;}S[1050000];
inline void tag1(int x,ll p){
S[x].v1=p+S[x].vc;
S[x].v=p+S[x].v2;
S[x].t1=p;
}
inline void tag2(int x,ll p){
S[x].v2=p+S[x].vc;
S[x].v=p+S[x].v1;
S[x].t2=p;
}
inline void pb(int x){
if(S[x].t1){
tag1(x<<1,S[x].t1);
tag1(x<<1|1,S[x].t1);
S[x].t1=0;
}
if(S[x].t2){
tag2(x<<1,S[x].t2);
tag2(x<<1|1,S[x].t2);
S[x].t2=0;
}
}
inline void up(int x){
S[x].v1=min(S[x<<1].v1,S[x<<1|1].v1);
S[x].v2=min(S[x<<1].v2,S[x<<1|1].v2);
S[x].vc=min(S[x<<1].vc,S[x<<1|1].vc);
S[x].v=min(S[x<<1].v,S[x<<1|1].v);
}
void same1(int x,int a,int b,int c,int d,ll p){
if(c<=a&&b<=d){tag1(x,p);return;}
pb(x);
int mid=(a+b)>>1;
if(c<=mid)same1(x<<1,a,mid,c,d,p);
if(d>mid)same1(x<<1|1,mid+1,b,c,d,p);
up(x);
}
void same2(int x,int a,int b,int c,int d,ll p){
if(c<=a&&b<=d){tag2(x,p);return;}
pb(x);
int mid=(a+b)>>1;
if(c<=mid)same2(x<<1,a,mid,c,d,p);
if(d>mid)same2(x<<1|1,mid+1,b,c,d,p);
up(x);
}
void change(int x,int a,int b,int c,ll p){
if(a==b){
S[x].vc=p;
S[x].v1=p+S[x].t1;
S[x].v2=p+S[x].t2;
S[x].v=p+S[x].t1+S[x].t2;
return;
}
pb(x);
int mid=(a+b)>>1;
c<=mid?change(x<<1,a,mid,c,p):change(x<<1|1,mid+1,b,c,p);
up(x);
}
ll ask(int x,int a,int b,int c,int d){
if(c<=a&&b<=d)return S[x].v;
pb(x);
int mid=(a+b)>>1;ll t=1LL<<60;
if(c<=mid)t=ask(x<<1,a,mid,c,d);
if(d>mid)t=min(t,ask(x<<1|1,mid+1,b,c,d));
return up(x),t;
}
int main(){
n=get(),w=get();
for(i=1;i<=n;i++)a[i]=10LL*get(),b[i]=b[i-1]+get(),c[i]=i;
for(sort(c+1,c+n+1,cmp),T.insert(0),T.insert(n+1),i=n;i;i--){
T.insert(c[i]);
it=T.find(c[i]);
it--,j=*it,l[c[i]]=*it+1;
if(j)it--,add(c[i],*it+1,j,a[c[i]]);
it=T.find(c[i]);
it++,j=*it;
if(j<=n)add(j,l[c[i]],c[i],a[c[i]]);
}
for(i=j=1;i<=n;i++){
same1(1,1,n,l[i],i,a[i]);
same2(1,1,n,i,i,a[i]);
for(k=g[i];k;k=nxt[k])same2(1,1,n,vl[k],vr[k],vw[k]);
while(b[i]-b[j-1]>w)j++;
f=ask(1,1,n,j,i)+w-b[i];
if(i<n)change(1,1,n,i+1,f+b[i]);
}
return printf("%lld.%d",f/10,f%10),0;
}

  

BZOJ4268 : 小强的书架的更多相关文章

  1. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

  2. [BZOJ1861][Zjoi2006]Book 书架

    [BZOJ1861][Zjoi2006]Book 书架 试题描述 小T有一个很大的书柜.这个书柜的构造有些独特,即书柜里的书是从上至下堆放成一列.她用1到n的正整数给每本书都编了号. 小T在看书的时候 ...

  3. Android分享一款漂亮的折叠书架菜单

    一个Android折叠书架菜单,效果极佳,给人的视觉感觉很好,便于使用. FoldingMenu

  4. [转载]我的Java后端书架 (2016年暖冬4.0版)

      [转载]我的Java后端书架 (2016年暖冬4.0版) ps:最近正在初学Java,有一些其他语言的底子,但是还是要好好看书,好好练习,网上找了好久,都没有这份书单来的实用,特意转载过来,方便以 ...

  5. BZOJ 1861: [Zjoi2006]Book 书架

    1861: [Zjoi2006]Book 书架 Time Limit: 4 Sec  Memory Limit: 64 MBSubmit: 1290  Solved: 740[Submit][Stat ...

  6. 基于HT的CSG功能构建HTML5的3D书架

    构造实体几何CSG全称Constructive solid geometry,是3D计算机图形学中构建模型的常用技术,可通过合并Union.相减Subtraction和相交Intersction的三种 ...

  7. 【代码笔记】iOS-点击加号增加书架,点击减号减少书架

    一,效果图. 二,工程图. 三,代码. ReaderViewController.h #import <UIKit/UIKit.h> @interface ReaderViewContro ...

  8. 【BZOJ-1926】粟粟的书架 二分 + 前缀和 + 主席树

    1926: [Sdoi2010]粟粟的书架 Time Limit: 30 Sec  Memory Limit: 552 MBSubmit: 616  Solved: 238[Submit][Statu ...

  9. BZOJ 1861: [Zjoi2006]Book 书架 splay

    1861: [Zjoi2006]Book 书架 Description 小T有一个很大的书柜.这个书柜的构造有些独特,即书柜里的书是从上至下堆放成一列.她用1到n的正整数给每本书都编了号. 小T在看书 ...

随机推荐

  1. python---基础知识回顾(一)(引用计数,深浅拷贝,列表推导式,lambda表达式,命名空间,函数参数逆收集,内置函数,hasattr...)

    一:列表和元组(引用计数了解,深浅拷贝了解) 序列:序列是一种数据结构,对其中的元素按顺序进行了编号(从0开始).典型的序列包括了列表,字符串,和元组 列表是可变的(可以进行修改),而元组和字符串是不 ...

  2. MongoDB-3.4搭建副本集

    搭建副本集 1:首先创建3台虚拟机作为配置环境 IP1:192.168.101.175 IP2:192.168.101.176 IP3:192.168.101.177 2.下载MongoDB 3.4版 ...

  3. Asp.net 子web application的Session共享

    需求提出: 网站: 父Web Application: http://www.test.com/ 子Web Application 1: http://www.test.com/child1 子Web ...

  4. 图的最短路径-----------SPFA算法详解(TjuOj2831_Wormholes)

    这次整理了一下SPFA算法,首先相比Dijkstra算法,SPFA可以处理带有负权变的图.(个人认为原因是SPFA在进行松弛操作时可以对某一条边重复进行松弛,如果存在负权边,在多次松弛某边时可以更新该 ...

  5. SQLServer xp_instance_regread returned error 5,Access is denied(配置最小权限)

    公司一套智能巡检系统,客户需要最小的权限去给这套系统使用:配置完后发现很多权限报错,有一条是关于xp_instance_regread读系统注册表error 5的报错.常理error 5.是属于系统权 ...

  6. ASP.NET应用技巧:非托管COM组件的使用

    众所周知,asp.net是基于通用语言运行库创建的,也就是所谓的托管执行环境.生成的代码称为托管代码.编译器能够从源代码的描述中产生元数据信息,而运行库又从元数据中获得托管代码的信息.而我们编写的组件 ...

  7. ASP.NET结合COM组件发送Email

    在开发电子邮件发送程序的时候,我们经常需要使用到相应的组件,其实不需要第三方的组件(例如:Jmail)照常可以做到发送Email的功能. 在系统目录(如c:/winnt或c:/windows)的sys ...

  8. jenkins 使用Git持续构建

    为jenkins添加git插件. 在Available tab页中找到Git Plugin 点击下方的Install without Restart安装插件. 插件安装完毕后,我们需要在jenkins ...

  9. KnockoutJs学习笔记(十一)

    enable binding往往作用于form elements,比如input.select和textarea等.包含enable binding的DOM元素会依照enable binding参数的 ...

  10. .NetCore 使用AutoMapper

    添加引用 AutoMapper AutoMapper.Extensions.Microsoft.DependencyInjection 注册服务 services.AddAutoMapper(); 配 ...