牛客小白月赛111 E-构造矩形

题目:E 构造矩形

题目链接:E-构造矩形_牛客小白月赛111

题意:\(n\) 条长度为 \(m\) 且互不重合的线段。第 \(i\) 条线段的两整数端点分别为 \((a_i, 0)\)\((a_i, m)\)。每条线段上有 \(m+1\) 个整数点。你需要选择两条不同的线段,并在每条线段上各选择两个不同的整数点,使得这四个点连接构成的四边形是个长减去宽为 \(k\) 的矩形。求选择方案数。

输入描述:第一行输入三个整数 \(n,m,k \left(1\le n,m \le 10^5;\ 1 \le k < m\right)\) 代表线段条数、线段的长度、要求构成的矩形长宽之差;第二行输入 \(n\) 个整数 \(a_1, a_2, \dots, a_n \left(1\le a_1 \lt a_2 \lt \dots \lt a_n \le 10^5\right)\)代表第 \(i\) 条线段端点的横坐标。

输出描述:输出一个整数,代表一共有多少种选择方案。答案不会超过 \(10^{18}\)

分析:

设线段上截取的长度为 \(h\),线段间距离为 \(x\)。分两种情况:

  • 情况一:当 \(h\) 为宽,\(x\) 为长时,有 \(0<h=x-k\leq m\),即 \(k<x\leq m+k\)
  • 情况二:当 \(h\) 为长,\(x\) 为宽时,有 \(0<h=x+k\leq m\),即 \(0<x\leq m-k\)

对于每条线段,我们只需要考虑比其横坐标值大(避免重复计算答案)且线段间距离符合上述条件的线段即可。

因在长度为 \(m\) 的线段上截取长度为 \(h\) 的线段有 \((m-h+1)\) 种方案,故对于第 \(i\) 条线段有:

  • 在情况一下可选方案数为 \(\sum \lbrace m-(a_j-a_i-k)+1\rbrace \left(k<a_j-a_i\leq m+k 即 k+a_i<a_j\leq m+a_i+k\right)\) ,设 \(j\in [L1_i,R1_i]\) 对累加式进一步化简得 $(R1_i-L1_i+1)\times (m+a_i+1+k)-\sum_{j=L1_i}^{R1_i}a_j $;
  • 在情况二下可选方案数为 \(\sum \lbrace m-(a_j-a_i+k)+1\rbrace \left(0<a_j-a_i\leq m-k即a_i<a_j\leq m+a_i-k \right)\),设 \(j\in [i+1,R2_i]\) 对累加式进一步化简得 $(R2_i-i)\times (m+a_i+1-k)-\sum_{j=i+1}^{R2_i}a_j $。

故总方案数为 \(\sum_{i=1}^n \lbrace(R1_i-L1_i+1)\times (m+a_i+1+k)+(R2_i-i)\times (m+a_i+1-k)-(\sum_{j=L1_i}^{R1_i}a_j+\sum_{j=L2_i}^{R2_i}a_j) \rbrace\)

解题技巧:分类讨论确定范围+累加累乘式化简(化简为更易维护的式子)

实现:二分(快速获得\(L1_i\)\(R1_i\)\(R2_i\))+前缀和(快速求得\(\sum_{j=L1_i}^{R1_i}a_j+\sum_{j=L2_i}^{R2_i}a_j\)

参考代码:

#include<bits/stdc++.h>
#define int long long
using namespace std;
#define endl '\n'

const int N=1e5+10;
int n,m,k,a[N],pre[N],ans; 

void solve(){
	cin>>n>>m>>k;
	for(int i=1;i<=n;i++) cin>>a[i],pre[i]=pre[i-1]+a[i];
	for(int i=1;i<=n;i++){
		int L1=upper_bound(a+1,a+1+n,k+a[i])-a;
		int R1=upper_bound(a+1,a+1+n,m+a[i]+k)-a-1;
		int R2=upper_bound(a+1,a+1+n,m+a[i]-k)-a-1;
		ans+=(R1-L1+1)*(m+a[i]+1+k)+(R2-i)*(m+a[i]+1-k);
		ans-=pre[R1]-pre[L1-1]+pre[R2]-pre[i];
	}
	cout<<ans;
}

signed main(){
	ios::sync_with_stdio(false);
	cin.tie(0),cout.tie(0);
	int T=1; 
	//cin>>T;
	while(T--) solve();
	return 0;
}


posted @ 2025-03-09 15:39  jojo_ojoj  阅读(30)  评论(0)    收藏  举报
/*