• 【CF875E】Delivery Club 二分+线段树


    【CF875E】Delivery Club

    题意:有n个快递需要依次接收,这n个快递分部在x轴上,第i个快递的位置是xi。有两个快递员,一开始分别在s0,s1,你可以任意安排哪个人收哪个快递,前提是一个快递员收快递是另一个快递员不能移动(也就是说他只有在收快递时能移动),并且要保证任何时候两人的距离不超过k。问你k最小是多少。

    n<=10^5,xi<=10^9

    题解:二分是显然的。我们可以用f[i][a][b]表示收第i个快递时,两个快递员一个在a,一个在b是否可行,又因为a或b一定等于i,所以我们可以省掉一维。我们还可以用线段树再省一维。因为在收第i+1个快递时,要么是在i处的快递员走到i+1,此时与i+1距离超过k的位置a都变成了不合法的,可以用线段树区间清零搞定;要么是在a处的快递员走到i+1。用线段树很容易维护这些东西。

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #define lson x<<1
    #define rson x<<1|1
    using namespace std;
    const int maxn=100010;
    int n;
    int v[maxn],p[maxn],rnk[maxn];
    bool s[maxn<<2];
    inline int Abs(const int &a) {return a>0?a:-a;}
    bool cmp(const int &a,const int &b)
    {
    	return v[a]<v[b];
    }
    inline void pushdown(int x)
    {
    	if(!s[x])	s[lson]=s[rson]=0;
    }
    void modify(int l,int r,int x,int a)
    {
    	if(l==r)
    	{
    		s[x]=1;
    		return ;
    	}
    	pushdown(x);
    	int mid=(l+r)>>1;
    	if(a<=mid)	modify(l,mid,lson,a);
    	else	modify(mid+1,r,rson,a);
    	s[x]=s[lson]|s[rson];
    }
    void updata(int l,int r,int x,int a,int b)
    {
    	if(a>b)	return ;
    	if(a<=l&&r<=b)
    	{
    		s[x]=0;
    		return ;
    	}
    	pushdown(x);
    	int mid=(l+r)>>1;
    	if(a<=mid)	updata(l,mid,lson,a,b);
    	if(b>mid)	updata(mid+1,r,rson,a,b);
    	s[x]=s[lson]|s[rson];
    }
    bool check(int len)
    {
    	int i,l,r,mid;
    	s[1]=0;
    	modify(1,n,1,rnk[1]);
    	for(i=3;i<=n;i++)
    	{
    		l=1,r=rnk[i];
    		while(l<r)
    		{
    			mid=(l+r)>>1;
    			if(v[p[mid]]<v[i]-len)	l=mid+1;
    			else	r=mid;
    		}
    		updata(1,n,1,1,l-1);
    		l=rnk[i],r=n;
    		while(l<r)
    		{
    			mid=(l+r)>>1;
    			if(v[p[mid]]<=v[i]+len)	l=mid+1;
    			else	r=mid;
    		}
    		updata(1,n,1,l,n);
    		if(Abs(v[i]-v[i-1])<=len)	modify(1,n,1,rnk[i-1]);
    		if(!s[1])	return 0;
    	}
    	return 1;
    }
    inline int rd()
    {
    	int ret=0,f=1;	char gc=getchar();
    	while(gc<'0'||gc>'9')	{if(gc=='-')	f=-f;	gc=getchar();}
    	while(gc>='0'&&gc<='9')	ret=ret*10+(gc^'0'),gc=getchar();
    	return ret*f;
    }
    int main()
    {
    	n=rd()+2;
    	int i,l=0,r=0,mid;
    	for(i=1;i<=n;i++)	v[i]=rd(),r=max(r,v[i]),p[i]=i;
    	sort(p+1,p+n+1,cmp);
    	for(i=1;i<=n;i++)	rnk[p[i]]=i;
    	v[0]=-1000000000,v[n+1]=1000000000;
    	l=Abs(v[2]-v[1]);
    	while(l<r)
    	{
    		mid=(l+r)>>1;
    		if(check(mid))	r=mid;
    		else	l=mid+1;
    	}
    	printf("%d",r);
    	return 0;
    }
  • 相关阅读:
    从远程库克隆
    添加远程库
    远程仓库
    删除文件
    xml 解析的四种方式
    遍历Map
    Spring 和SpringMVC 的父子容器关系
    JDK各版本新特性!
    看啦这么就别人的博客 我也来写一篇! Object转换其他类型
    手机访问电脑搭建的服务器地址
  • 原文地址:https://www.cnblogs.com/CQzhangyu/p/8157512.html
Copyright © 2020-2023  润新知