[CF1513F]Swapping Problem

Swapping Problem

题解

很水的一道题

我们考虑交换那些数时会对答案产生贡献。
我们可以先将所有的线段分成 a > b a>b a>b a < b a<b a<b的两类,分别记作 x , y x,y x,y,很明显,同一类中的交换,绝对是不优的。
而不同的类中的交换,若 x , y x,y x,y没有重合部分,那么也是不优的。对于有重合部分的 x , y x,y x,y,它们所产生的贡献就是它们重合部分的两倍。这个手画一下就知道了
所以,我们要做的是,从两个集合中找出重合部分最长的两个线段。

我们可以先将所有的 y y y按左端点排序,再去掉所有被包含的线段,即排序后右端点不大于前者右端点的。
很明显,子线段是不会优于母线段的。
这样,我们就可以保证无论是左端点还是右端点,都是不降的了。
对于每个 x x x,我们先二分出与其左端点相交的最近的和与右端点相交的最近的线段,这两者明显对于所有没有包含于它的线段是最优的。
它们之间的线段是整段都被包含,它们的长度就是它们的贡献,我们只需要用st表找出它们的最大长度即可。

时间复杂度 O ( n l o g   n ) O\left(nlog\,n\right) O(nlogn)

源码

#include<bits/stdc++.h>
using namespace std;
#define MAXN 200005
#define lowbit(x) (x&-x)
#define reg register
typedef long long LL;
typedef unsigned long long uLL;
typedef unsigned int uint;
const int INF=0x7f7f7f7f;
const int jzm=233;
const int mo=998244353;
const double Pi=acos(-1.0);
typedef pair<int,int> pii;
const double PI=acos(-1.0);
template<typename _T>
_T Fabs(_T x){return x<0?-x:x;}
template<typename _T>
void read(_T &x){
	_T f=1;x=0;char s=getchar();
	while(s>'9'||s<'0'){if(s=='-')f=-1;s=getchar();}
	while('0'<=s&&s<='9'){x=(x<<3)+(x<<1)+(s^48);s=getchar();}
	x*=f;
}
int n,tot1,tot2,lg[MAXN],st[22][MAXN];LL num,ans;
struct ming{int a,b;}s[MAXN],up[MAXN],dn[MAXN];
bool cmp(ming x,ming y){return x.a<y.a;}
int Cover(ming x,ming y){int l=max(x.a,y.a),r=min(x.b,y.b);if(l>r)return 0;return r-l;}
int query(int l,int r){if(l>r)return 0;int len=r-l+1;return max(st[lg[len]][l],st[lg[len]][r-(1<<lg[len])+1]);}
int main(){
	read(n);
	for(int i=1;i<=n;i++)read(s[i].a);
	for(int i=1;i<=n;i++)read(s[i].b),ans+=1ll*Fabs(s[i].a-s[i].b);
	for(int i=1;i<=n;i++)(s[i].a<s[i].b?up[++tot1]:dn[++tot2])=s[i];
	for(int i=1;i<=tot2;i++)swap(dn[i].a,dn[i].b);
	sort(dn+1,dn+tot2+1,cmp);
	for(int i=1;i<=tot2;i++)dn[i].b=max(dn[i-1].b,dn[i].b);  
	for(int i=2;i<=tot2;i++)lg[i]=lg[i>>1]+1;
	for(int i=1;i<=tot2;i++)st[0][i]=dn[i].b-dn[i].a;
	for(int i=1;i<=20;i++)
		for(int j=1;j<=tot2-(1<<i)+1;j++)
			st[i][j]=max(st[i-1][j],st[i-1][j+(1<<i-1)]);
	for(int i=1;i<=tot1;i++){
		int al,ar,l=1,r=tot2;
		while(l<r){int mid=l+r+1>>1;if(dn[mid].a<=up[i].a)l=mid;else r=mid-1;}al=l;
		l=1,r=tot2;while(l<r){int mid=l+r>>1;if(dn[mid].b>=up[i].b)r=mid;else l=mid+1;}ar=l;
		num=max(num,1ll*max(max(Cover(up[i],dn[al]),Cover(up[i],dn[ar])),query(al+1,ar-1)));
		//printf("%d %d %d:%d %d %d %d\n",i,up[i].a,up[i].b,dn[al].a,dn[al].b,dn[ar].a,dn[ar].b);
	}
	printf("%lld\n",ans-2ll*num);
	return 0;
}

谢谢!!!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Hotswapping是指在应用程序运行过程中实时修改代码并应用到正在运行的应用程序中,而无需重新启动应用程序。对于Spring Boot应用程序来说,Hotswapping可以提高开发效率,加快代码调试和验证的速度。 Spring Boot支持两种方式的Hotswapping:热部署和热重启。 热部署是指在不重新启动应用程序的情况下,替换或添加部分代码。这可以通过使用工具如JRebel来实现。使用JRebel,当我们修改了Spring Boot项目中的代码后,只需要手动触发重新加载代码,应用程序会动态地将最新的代码应用到正在运行的应用程序中。这样我们就可以立即看到我们的更改效果,无需重新启动应用程序。 另一种方式是热重启。在Spring Boot中,我们可以使用Spring Loaded或DevTools来实现。这些工具通过在运行时监测类文件的更改来实现热重启。当我们修改了代码后,应用程序会自动重新启动,并将最新的代码重新加载到内存中。虽然这样会有一定的延迟和性能开销,但它是一种更加方便和自动化的方式。 无论是热部署还是热重启,Hotswapping都大大加快了开发过程中的代码调试和验证的速度。我们可以实时地修改和测试我们的代码,而无需重新启动整个应用程序。这样不仅提高了开发效率,还减少了等待和重复操作的时间,提高了开发人员的工作效率。同时,Hotswapping也适用于生产环境中的快速修复和调整,提高了应用程序的可维护性和稳定性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值