Codeforces 875E Delivery Club 妙哉!

本文介绍了一种关于两人在数轴上按序访问点的任务分配算法,通过倒序求解及区间更新的方式,实现了高效的二分查找策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目链接:传送门

题目大意:给定n, s1, s2和数轴上n个点{a_n},编号1~n,要求给一开始分别在s1和s2的两个人分配任务,使得每个点按照 编号顺序 被恰好一个人访问,并且使得任意时刻两个人的距离的最大值最小。n<=1e5,s1, s2, ai<=1e9


题解:显然这个东西摆明了是要二分答案,然后,不难发现二分出来的答案的可行性可以用dp验证,大概就是dp[i]表示第i个点被访问是否(在这个二分答案下)可行。

这个转移显然是一段区间的或,可以用线段树维护一下,复杂度O(n(lgn)^2),可以通过,但是代码复杂度和时间复杂度都略高。

一个很显然的想法就是贪心,直观的贪心就是正着考虑,然后各种讨论,但是大概没有什么好的思路。

现在我们用一个转化思路的技巧:我们不求从s1,s2能不能完成任务,我们求,s1,s2在什么地方能完成任务;

这样球出来之后只有判断一下s1和s2在不在范围内即可。

显然在这里s1和s2无本质区别,下文用“当前这个人”和"另一个人"来分别表示一个人和另一个人。

这显然是一个倒序求解的问题,因为只做第n个任务,当前这个人的区间是显然的,就是[a[n]-二分出来的答案, a[n]+二分出来的答案];

而我们求得就是做1~n个任务的区间。算法流程如下(x为二分出来的答案):

L <- a[n] - x
R <- a[n] + x
for i <- (n-1) to 1 do
	if In_Range(a[i], L, R)
		L <- a[i] - x
		R <- a[i] + x
	else
		L <- max(L, a[i] - x)
		R <- min(R, a[i] + x)
End For

return  In_Range(s1, L, R) or In_Range(s2, L, R)

这段代码的大意就是,设置初始区间[L, R]为[a[n]-x, a[n]+x],然后i从n-1逆序枚举;

如果a[i]在当前区间[L,R]里,就把[L,R]设为以a[i]为中心x为半径的区间(下文记作a[i]的x-y区间)

否则[L, R]取为它和a[i]的x-y区间的交集。下文把[L, R]叫做当前区间,也就是当前这个人应该在的区间。

问什么是对的呢?读者可以尽量思考一下!


首先我们考虑a[i]在当前区间内的情况;假设当前这个人在编号为j的点上,显然有j>i;

那么我们证明在编号为i的人一定  可以  是另一个人。

假设不可以,即i也是当前这个人呆过的地方,那么假设当当前这个人在i的时候,另一个人在k;

并且不妨假设当前的人从i跳到j的时候,另一个人一直呆在k(否则你可以选择最后没有变化的那一段,情况不会改变)

显然有a[i]应当在a[k]的x-y区间内,而i最终直接跳到了j(如果不直接的话,那么假设i先到了t,那么t应该取代i的位置),

这意味着a[j]也是在a[k]的x-y区间内的,否则因为另一个人没动所以就到不了j了。

那么如果存在这种情况,我们不难发现,a[p]在a[q]的x-y区间内等价于a[q]在a[p]的x-y区间内,

因此上文等价于a[k]和a[j]在a[i]的x-y区间内,因此另一个人可以直接从a[k]跳到a[j],也就是a[k]和a[j]可以看作是同一人,这种情况下a[i]就是另一个人

上文的证明思路就是,如果i可以是当前这个人并且有解,那么把i换成另一个人也可以保证有解。

因此,把“当前这个人”和"另一个人"互换,即把另一个人看成当前这个人,那么当前区间显然就是[a[i]-x, a[i]+x]。


下面在看else部分,即a[i]不在当前区间内的情况,那么a[i]一定不会是当前这个人。这是定义,请参照上文。

因此,a[i]就是另一个人,这意味着,当前这个人也一定要在a[i]的x-y区间内,因此两个区间取交即可。

这样最后两个人只要有一个人在算出来的区间内(即他是当前这个人),二分出来的x就是ok的。

代码实现注意一开始二分的下界应该设成abs(s1-s2),否则会gg。


代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define inrange(x) ((x)>=L&&(x)<=R)
#define N 100010
#define INF 1000000000
using namespace std;
int a[N],n,s1,s2;
inline bool check(int x)
{
	int L=a[n]-x,R=a[n]+x;
	for(int i=n-1;i;i--)
		if(inrange(a[i])) L=a[i]-x,R=a[i]+x;
		else L=max(L,a[i]-x),R=min(R,a[i]+x);
	return inrange(s1)||inrange(s2);
}
inline int gabs(int x)
{
	return x>0?x:-x;
}
int main()
{
	scanf("%d%d%d",&n,&s1,&s2);
	for(int i=1;i<=n;i++) scanf("%d",&a[i]);
	int L=gabs(s1-s2),R=INF,mid=(L+R)>>1;
	while(L<=R)
	{
		if(check(mid)) R=mid-1;
		else L=mid+1;mid=(L+R)>>1;
	}
	printf("%d\n",L);return 0;
}


内容概要:本文探讨了在MATLAB/SimuLink环境中进行三相STATCOM(静态同步补偿器)无功补偿的技术方法及其仿真过程。首先介绍了STATCOM作为无功功率补偿装置的工作原理,即通过调节交流电压的幅值和相位来实现对无功功率的有效管理。接着详细描述了在MATLAB/SimuLink平台下构建三相STATCOM仿真模型的具体步骤,包括创建新模型、添加电源和负载、搭建主电路、加入控制模块以及完成整个电路的连接。然后阐述了如何通过对STATCOM输出电压和电流的精确调控达到无功补偿的目的,并展示了具体的仿真结果分析方法,如读取仿真数据、提取关键参数、绘制无功功率变化曲线等。最后指出,这种技术可以显著提升电力系统的稳定性与电能质量,展望了STATCOM在未来的发展潜力。 适合人群:电气工程专业学生、从事电力系统相关工作的技术人员、希望深入了解无功补偿技术的研究人员。 使用场景及目标:适用于想要掌握MATLAB/SimuLink软件操作技能的人群,特别是那些专注于电力电子领域的从业者;旨在帮助他们学会建立复杂的电力系统仿真模型,以便更好地理解STATCOM的工作机制,进而优化实际项目中的无功补偿方案。 其他说明:文中提供的实例代码可以帮助读者直观地了解如何从零开始构建一个完整的三相STATCOM仿真环境,并通过图形化的方式展示无功补偿的效果,便于进一步的学习与研究。
### Codeforces 887E Problem Solution and Discussion The problem **887E - The Great Game** on Codeforces involves a strategic game between two players who take turns to perform operations under specific rules. To tackle this challenge effectively, understanding both dynamic programming (DP) techniques and bitwise manipulation is crucial. #### Dynamic Programming Approach One effective method to approach this problem utilizes DP with memoization. By defining `dp[i][j]` as the optimal result when starting from state `(i,j)` where `i` represents current position and `j` indicates some status flag related to previous moves: ```cpp #include <bits/stdc++.h> using namespace std; const int MAXN = ...; // Define based on constraints int dp[MAXN][2]; // Function to calculate minimum steps using top-down DP int minSteps(int pos, bool prevMoveType) { if (pos >= N) return 0; if (dp[pos][prevMoveType] != -1) return dp[pos][prevMoveType]; int res = INT_MAX; // Try all possible next positions and update 'res' for (...) { /* Logic here */ } dp[pos][prevMoveType] = res; return res; } ``` This code snippet outlines how one might structure a solution involving recursive calls combined with caching results through an array named `dp`. #### Bitwise Operations Insight Another critical aspect lies within efficiently handling large integers via bitwise operators instead of arithmetic ones whenever applicable. This optimization can significantly reduce computation time especially given tight limits often found in competitive coding challenges like those hosted by platforms such as Codeforces[^1]. For detailed discussions about similar problems or more insights into solving strategies specifically tailored towards contest preparation, visiting forums dedicated to algorithmic contests would be beneficial. Websites associated directly with Codeforces offer rich resources including editorials written after each round which provide comprehensive explanations alongside alternative approaches taken by successful contestants during live events. --related questions-- 1. What are common pitfalls encountered while implementing dynamic programming solutions? 2. How does bit manipulation improve performance in algorithms dealing with integer values? 3. Can you recommend any online communities focused on discussing competitive programming tactics? 4. Are there particular patterns that frequently appear across different levels of difficulty within Codeforces contests?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值