【数学】Pair of Topics—CF1324D

Pair of Topics---CF1324D

思路

很明显,需要对 a i + a j > b i + b j a_i + a_j > b_i + b_j ai+aj>bi+bj 化简:
a i − b i > b j − a j a_i - b_i > b_j - a_j ai−bi>bj−aj
a i − b i > − ( a j − b j ) a_i - b_i > -(a_j - b_j) ai−bi>−(aj−bj)

令 c i = a i − b i c_i = a_i - b_i ci=ai−bi,则:
c i > − c j c_i > -c_j ci>−cj
c i + c j > 0 c_i + c_j > 0 ci+cj>0

所求变成:

满足 i < j i < j i<j 且 c i + c j > 0 c_i + c_j > 0 ci+cj>0 的数量。

可以看出,如果没有 i < j i < j i<j 这个要求,那么我们可以对 c c c 排序,遍历 i i i,对于每一个 c i c_i ci 用二分求出满足 c i + c j > 0 c_i + c_j > 0 ci+cj>0 的数量,再求和即可。

其实我们恰恰可以上边的方法求出答案 r e s res res,然后再执行 r e s / = 2 res~/=~2 res /= 2 就是在约束条件 i < j i < j i<j 下的答案。

因为我们用这个方法遍历每一个 c i c_i ci 的时候,都多计算了其中 i ′ > j ′ i' > j' i′>j′ 且 c i ′ + c j ′ > 0 c_i' + c_j' > 0 ci′+cj′>0 的数量,而这样的一对 c i ′ , c j ′ c_i', c_j' ci′,cj′ 在 i ( 遍历过程中的 i ) = j ′ ( 当前的 j ′ ) i(遍历过程中的i) = j'(当前的j') i(遍历过程中的i)=j′(当前的j′) 时都是同时满足两个条件的。所以我们多计算的数量等于应该计算的数量,最终 r e s res res 除以 2 2 2 就是本题正确的答案。

例如, i = 3 , j = 2 , c i = 666 , c j = − 666 i = 3, j = 2, c_i = 666, c_j = -666 i=3,j=2,ci=666,cj=−666,我们在用上百年那个方法的时候会将这种情况也计算在内。但如果将 i , j i, j i,j 对调,我们发现 i = 2 , j = 3 , c i = − 666 , c j = 666 i = 2, j = 3, c_i = -666, c_j = 666 i=2,j=3,ci=−666,cj=666 是同时满足两个条件的。同理,每一个满足两个条件的 i , j i, j i,j 都会其将 i , j i, j i,j 对调后的 i , j i, j i,j 都会错误地被当做正确情况计算在内。

C o d e Code Code

cpp 复制代码
#include <bits/stdc++.h>
#define int long long
#define sz(a) ((int)a.size())
#define all(a) a.begin(), a.end()
using namespace std;
using PII = pair<int, int>;
using i128 = __int128;
const int N = 2e5 + 10;

int n;
int c[N];

void solve(int Case) {
	cin >> n;
	for (int i = 1; i <= n; i ++) cin >> c[i];
	for (int i = 1; i <= n; i ++) {
		int b; cin >> b;
		c[i] -= b;
	}
	sort(c + 1, c + n + 1);
	
	int res = 0;
	for (int i = 1; i <= n; i ++) {
		int l = 1, r = n;
		while (l < r) {
			int mid = (l + r) / 2;
			if (c[i] + c[mid] > 0) {
				r = mid;
			} else {
				l = mid + 1;
			}
		}
		if (c[i] + c[l] > 0) {
			res += (n - l + 1) - (l <= i);
		}
	}
	cout << "       ";
	cout << res / 2 << "\n";
}

signed main() {
	cin.tie(0)->ios::sync_with_stdio(false);
	int T = 1;
//	cin >> T; cin.get();
	int Case = 0;
	while (++ Case <= T) solve(Case);
	return 0;
}
相关推荐
88号技师28 分钟前
2024年12月一区SCI-加权平均优化算法Weighted average algorithm-附Matlab免费代码
人工智能·算法·matlab·优化算法
IT猿手29 分钟前
多目标应用(一):多目标麋鹿优化算法(MOEHO)求解10个工程应用,提供完整MATLAB代码
开发语言·人工智能·算法·机器学习·matlab
88号技师30 分钟前
几款性能优秀的差分进化算法DE(SaDE、JADE,SHADE,LSHADE、LSHADE_SPACMA、LSHADE_EpSin)-附Matlab免费代码
开发语言·人工智能·算法·matlab·优化算法
一只小bit33 分钟前
数据结构之栈,队列,树
c语言·开发语言·数据结构·c++
我要学编程(ಥ_ಥ)1 小时前
一文详解“二叉树中的深搜“在算法中的应用
java·数据结构·算法·leetcode·深度优先
埃菲尔铁塔_CV算法1 小时前
FTT变换Matlab代码解释及应用场景
算法
沐泽Mu2 小时前
嵌入式学习-QT-Day05
开发语言·c++·qt·学习
许野平2 小时前
Rust: enum 和 i32 的区别和互换
python·算法·rust·enum·i32
chenziang12 小时前
leetcode hot100 合并区间
算法
chenziang12 小时前
leetcode hot100 对称二叉树
算法·leetcode·职场和发展