题目描述

  有一个陶瓷瓶周围有\(n\)个可以印花的位置。第\(i\)个与第\(i+1\)个位置之间的距离为\(d_i\),在第\(i\)个位置印图案要\(t_i\)秒。

  机器刚开始在\(0\)号位置,可以以\(1\)单位长度每秒的速度移动。

  一个位置只能印一个图案。

  现在有\(m\)秒,问你最多能印几个图案。

  保证时间不足以绕陶瓷瓶一圈。

  \(n\leq 100000\)

题解

  肯定是先往一边移动在移动到另外一边。

  不妨设先往右边移动,那么右边的距离就要\(\times 2\)。

  求出每边印\(i\)个印花最少要多少秒。

  然后把两边合并即可。

  考虑怎么求。

  显然印\(i+1\)个印花的最优方案所需要移动的最右端点肯定在印\(i\)个印花的右边。

  证明:考虑反证法。

  设\(f(i,j)\)为印\(i\)个印花且最右端点为\(j\)的代价,\(a(i,j)\)为在前\(i\)个端点印印花所需要的第\(j\)短时间。

  设印\(i\)个印花的最优方案所需要移动的最右端点为\(j\),\(i+1\)个的右端点是\(k(k<j)\)

  那么有\(f(i,j)<f(i,k),a(j,i+1)<a(k,i+1),f(i+1,j)>f(i+1,k)\)

  但是前两项加起来是第三项,所以不合法。

  然后就可以分治了。

  设当前要求印\(l\)个到\(r\)个的答案,答案区间为\([sl,sr]\)。

  先求出印\(mid=\frac{l+r}{2}\)个的答案和右端点位置\(k\),可以通过枚举右端点得到。

  \([l,mid-1]\)的右端点位置在\([sl,k]\),\([mid+1,r]\)的右端点位置在\([k,sr]\)

  然后分治下去即可。

  求前面\(i\)个位置最小的\(j\)个印印花的时间可以通过可持久化线段树得到。

  时间复杂度:\(O(n\log^2n)\)

代码

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<utility>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
int q;
char cc[10000010];
int tt;
int h[100010];
ll rd()
{
ll s=0;
int c;
while((c=cc[tt++])<'0'||c>'9');
s=c-'0';
while((c=cc[tt++])>='0'&&c<='9')
s=s*10+c-'0';
return s;
}
namespace seg
{
int ls[4000010];
int rs[4000010];
ll s[4000010];
int sz[4000010];
int cnt;
int insert(int p1,int &x,int l,int r)
{
int p=++cnt;
ls[p]=ls[p1];
rs[p]=rs[p1];
s[p]=s[p1]+h[x];
sz[p]=sz[p1]+1;
if(l==r)
return p;
int mid=(l+r)>>1;
if(x<=mid)
ls[p]=insert(ls[p],x,l,mid);
else
rs[p]=insert(rs[p],x,mid+1,r);
return p;
}
ll query(int p,int x,int l,int r)
{
if(l==r)
return (ll)x*h[l];
int mid=(l+r)>>1;
int lsz=sz[ls[p]];
if(x<=lsz)
return query(ls[p],x,l,mid);
return s[ls[p]]+query(rs[p],x-lsz,mid+1,r);
}
}
int rt[100010];
int n;
ll m;
ll d[100010];
int t[100010];
ll a[100010];
ll f1[100010];
ll f2[100010];
ll g1[100010];
ll g2[100010];
int b[100010];
int c[100010];
int e[100010];
int f[100010];
ll &mm=m;
void gao(int l,int r,int sl,int sr,ll *s)
{
if(l>r)
return;
int mid=(l+r)>>1;
ll ans=0x3fffffffffffffffll;
int i;
int m=sr;
for(i=sl;i<=sr;i++)
if(i>=mid&&a[i-1]<=mm)
{
ll v=a[i-1]+seg::query(rt[i],mid,0,q);
if(v<ans)
{
ans=v;
m=i;
}
}
s[mid]=ans;
gao(l,mid-1,sl,m,s);
gao(mid+1,r,m,sr,s);
}
void gao(ll *s)
{
memset(rt,0,sizeof rt);
seg::cnt=0;
int i;
for(i=1;i<=n;i++)
rt[i]=seg::insert(rt[i-1],c[i],0,q);
gao(1,n,1,n,s);
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("a.in","r",stdin);
freopen("a2.out","w",stdout);
#endif
fread(cc+1,10000000,1,stdin);
// scanf("%d%lld",&n,&m);
n=rd();
m=rd();
int i;
q=0;
for(i=1;i<=n;i++)
// scanf("%lld%lld",&d[i],&t[i]);
{
d[i]=rd();
t[i]=rd();
h[++q]=t[i];
}
sort(h+1,h+q+1);
q=unique(h+1,h+q+1)-h-1;
for(i=1;i<=n;i++)
t[i]=lower_bound(h+1,h+q+1,t[i])-h;
for(i=1;i<=n;i++)
{
a[i]=d[i];
c[i]=t[i];
}
for(i=1;i<=n;i++)
a[i]+=a[i-1];
gao(f1);
for(i=1;i<=n;i++)
a[i]*=2;
c[1]=0;
gao(g1);
reverse(t+2,t+n+1);
reverse(d+1,d+n+1);
for(i=1;i<=n;i++)
{
a[i]=d[i];
c[i]=t[i];
}
for(i=1;i<=n;i++)
a[i]+=a[i-1];
gao(f2);
for(i=1;i<=n;i++)
a[i]*=2;
c[1]=0;
gao(g2);
int ans=0;
for(i=1;i<=n;i++)
if(f1[i]<=m)
ans=max(ans,i);
for(i=1;i<=n;i++)
if(f2[i]<=m)
ans=max(ans,i);
int j;
j=n;
for(i=1;i<=n;i++)
{
while(j&&f1[i]+g2[j]>m)
j--;
if(!j)
break;
ans=max(ans,i+j-1);
}
j=n;
for(i=1;i<=n;i++)
{
while(j&&f2[i]+g1[j]>m)
j--;
if(!j)
break;
ans=max(ans,i+j-1);
}
printf("%d\n",ans);
return 0;
}

【XSY2732】Decalcomania 可持久化线段树 分治的更多相关文章

  1. BZOJ.4137.[FJOI2015]火星商店问题(线段树分治 可持久化Trie)

    BZOJ 洛谷 一直觉得自己非常zz呢.现在看来是真的=-= 注意题意描述有点问题,可以看BZOJ/洛谷讨论. 每个询问有两个限制区间,一是时间限制\([t-d+1,t]\),二是物品限制\([L,R ...

  2. BZOJ4012[HNOI2015]开店——树链剖分+可持久化线段树/动态点分治+vector

    题目描述 风见幽香有一个好朋友叫八云紫,她们经常一起看星星看月亮从诗词歌赋谈到 人生哲学.最近她们灵机一动,打算在幻想乡开一家小店来做生意赚点钱.这样的 想法当然非常好啦,但是她们也发现她们面临着一个 ...

  3. 2019.01.13 bzoj4137: [FJOI2015]火星商店问题(线段树分治+可持久化01trie)

    传送门 题意:序列上有nnn个商店,有两种事件会发生: sss商店上进购标价为vvv的一个物品 求编号为[l,r][l,r][l,r]之间的位置买ddd天内新进购的所有物品与一个数xxx异或值的最大值 ...

  4. 【xsy2818】 最近点 动态树分治+可持久化线段树

    题目大意:给你一颗n个节点的树,最初点集S为空. 有m次操作:往当前点集S中加入/删除一个点,询问点x至集合S中任意点的最小距离,回到第t次修改点集的操作后的状态. 数据范围:$n,m≤10^5$ 我 ...

  5. bzoj 4137 [FJOI2015]火星商店问题——线段树分治+可持久化01trie树

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4137 关于可持久化01trie树:https://www.cnblogs.com/LadyL ...

  6. 【BZOJ4137】火星商店问题(线段树分治,可持久化Trie)

    [BZOJ4137]火星商店问题(线段树分治,可持久化Trie) 题面 洛谷 BZOJ权限题 题解 显然可以树套树,外层线段树,内层可持久化Trie来做. 所以我们需要更加优美的做法.--线段树分治. ...

  7. [FJOI2015]火星商店问题(线段树分治,可持久化,Trie树)

    [FJOI2015]火星商店问题 前天考了到线段树分治模板题,全场都切了,就我不会QAQ 于是切题无数的Tyher巨巨就告诉我:"你可以去看看火星商店问题,看了你就会了." 第一道 ...

  8. [FJOI2015]火星商店问题(线段树分治+可持久化Trie)

    重新写一年前抄题解的那题,当时我啥都不会只是Ctrl+C,Ctrl+V写过的题,今天重新写一遍. 题解: 不会线段树分治,还是学一下这东西吧,这是我的第一道线段树分治. 首先对于特殊商品,可以直接可持 ...

  9. 【洛谷P4585】 [FJOI2015]火星商店问题 线段树分治+可持久化trie

    感觉这个线段树分治和整体二分几乎相同啊~ code: #include <bits/stdc++.h> #define MAX 100300 #define ll long long #d ...

随机推荐

  1. Django+nginx+uwsgi部署教程

    00-所需工具 xshell:https://www.netsarang.com/zh/downloading/?token=ZlZnVUNsWDJuM0VaZnVPUjZST1dwd0AzYlNte ...

  2. SQL SERVER按多字段查找重复的数据并删除只保留一条

    由于一次操作失误,给表中插入了多条重复的数据,所以就需要删除重复的数据只保留一条,一时想不到好方法,各种查资料,终于找到了,特意写到这里,方便以后自己用~ 查询: select A.n_PatentI ...

  3. Mike and strings CodeForces - 798B (简洁写法)

    题目链接 时间复杂度 O(n*n*|s| ) 纯暴力,通过string.substr()函数来构造每一个字符串平移后的字符串. #include <iostream> #include & ...

  4. git的用法步骤讲解

    1.创建全局的本地用户名 git config --global user.name "teamemory" git config --global user.email &quo ...

  5. from、where、group、with、having、order、union、limit 的使用

    顺序很重要 每次看数据库的一些语法时,都很自然的略过那一大堆的规则,比如说线下面这段select的语法: select [field1,field2...] func_namefrom table1, ...

  6. MYSQL 三元 函数

    mysql函数之流程控制-FreeOAhttp://www.freeoa.net/osuport/db/mysql-control-fun_2143.html mysql如何利用三元算法判断数字奇偶性 ...

  7. 使用Random类生成指定范围的随机数

    目的:要生成在[min,max]之间的随机整数 public class RandomTest { public static void main(String[] args) { ; ; Rando ...

  8. Windows BAT 命令下del 与 rd 命令

    https://blog.csdn.net/jigetage/article/details/81180757 RD 与 DEL 命令 windows bat 目录和文件的删除处理. 命令:RD,删除 ...

  9. servlet ServletContext

    一.Servlet简介 1.什么是Servlet Servlet 运行在服务端的Java小程序,是sun公司提供一套规范(接口),用来处理客户端请求.响应给浏览器的动态资源.但servlet的实质就是 ...

  10. Day 4-1 模块的导入方法和路径

    什么是模块? 在计算机程序的开发过程中,随着程序代码越写越多,在一个文件里代码就会越来越长,越来越不容易维护. 为了编写可维护的代码,我们把很多函数分组,分别放到不同的文件里,这样,每个文件包含的代码 ...