[ AT_agc009_c]Division into Two

题目传送门

大家都知道集合吧,原谅我喜欢说废话

解法

先钦定 A > B A>B A>B,

先把数排好序得到数组 a a a,考虑先解决集合 X X X的问题,

设计状态:

明显只有一维( n < = 1 e 5 n<=1e5 n<=1e5),所以有:
f i : X 集合最后放的是第 i 个数,对于前 i 个数来说 X , Y 都合法的方案数 f_i:X集合最后放的是第i个数,对于前i个数来说X,Y都合法的方案数 fi:X集合最后放的是第i个数,对于前i个数来说X,Y都合法的方案数

发现后 ( n − i ) (n-i) (n−i)个放在 Y Y Y的数我们未保证合法,但是我们之后特判一下就好了

状态转移

设 f i f_i fi由 f j f_j fj转移而来

考虑有哪些 j j j可以贡献:

  1. i > j i>j i>j(废话)

  2. a i − a j ≥ A a_i-a_j\ge A ai−aj≥A(差值大于 A A A)

  3. max ⁡ { a k − a k − 1 } ≥ B , k ∈ ( j , i ) \max\{a_k-a_{k-1}\}\ge B,k\in(j,i) max{ak−ak−1}≥B,k∈(j,i)(满足 Y Y Y集合的要求)

则: f i = ∑ f j f_i=\sum f_j fi=∑fj

code:

复制代码
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
const int mod = 1e9 + 7,N=1e5+7;
int n,l,r;
int f[N],sum[N];
ll A,B;
ll a[N];
int main(){
	scanf("%d%lld%lld",&n,&A,&B);
	if(A<B) swap(A,B);
	for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
	for (int i=1;i+2<=n;++i)
        if (a[i+2]-a[i]<B) return puts("0"),0;
	a[0]=0;
	f[0]=sum[0]=1;
	for(int i=1;i<=n;i++) {
		while(a[i]-a[r+1]>=A) r++;
		if(l<=r) {
			f[i]=(1ll*f[i]+1ll*sum[r])%mod;
			if(l) f[i]=(1ll*f[i]-1ll*sum[l-1]+mod)%mod;
		}
		sum[i]=(1ll*sum[i-1]+1ll*f[i])%mod;
		if(a[i]-a[i-1]<B) l=i-1;
	}
	int ans=0;
	for(int i=n;~i;i--){	
		ans=(1ll *ans+1ll*f[i])	%mod;
		if(i<n && a[i+1]-a[i] <B) break;
	}
	printf("%d\n",ans);
}

TXL

相关推荐
大明者省7 分钟前
WSL2 Ubuntu22.04 GPU训练环境配置指南
人工智能·算法·计算机视觉
WWJA王文举1 小时前
I²C通信完整流程详解:START、地址、ACK、数据、Repeated START和STOP一次讲透
c语言·开发语言
白狐_7982 小时前
408数据结构第8章:排序②——性质对比秒杀、场景选择与外部排序
java·数据结构·算法
zander2582 小时前
LeetCode 84:柱状图中的最大矩形——单调栈如何确定左右边界
java·数据结构·算法
Shell运维手记2 小时前
Linux 常用基础命令学习笔记
linux·运维·笔记·学习·算法·github
qq_448011163 小时前
C语言中的动态内存分配
c语言·开发语言·php
杨航 AI3 小时前
O(n log n):线性对数原理拆解 这个是排序算法的黄金复杂度之一。
算法·排序算法
船厂电气自动化ai大模型3 小时前
AI大模型与数学 第32课 函数凹凸性与二阶导数:拐点求解、凹凸区间计算(10道二阶导数计算题)
数据结构·人工智能·python·深度学习·算法
动词ing3 小时前
【学习笔记】C语言(数组指针与指针数组+字符数组+函数+参数传递+字符串作为形参+递归函数+指针函数+回调函数+结构体嵌套+内存动态分配函数)
c语言·笔记·学习
旖旎夜光3 小时前
LeetCode 3:无重复字符的最长子串(滑动窗口) —— 题解
数据结构·c++·算法·leetcode·滑动窗口