题目大意:让你找出所有\(ai+aj > bi+bj\)(i > j)
??其实这题不用在意\(i > j\)只要把\(i\neq j\)并且符合条件的一对数记做一个答案就行了。。。(显然通过\(i和j\)交换必有\(i > j\))。然后我们把\(ai+aj > bi+bj\)变形可得\((ai-bi)+(aj-aj) > 0\)所以我们把所有的\(ai\)和\(bi\)做差
得到数组\(d\),那么只有\(d\)数组中存在一对数满足两数之和大于0就是答案的一个解,我们的任务就是计算\(d\)数组中有多少对这样的数。
??我们对数组\(d\)进行排序,如果一个数\(di\)与另一个比\(di\)小的数\(dj\)相加和大于\(0\),那么所有大于\(dj\)的数与\(di\)相加肯定都大于0,这些数的数量就是\(i-j\)。我们利用这个性质,尺取出所有的结果即可,如果想进一步降低时间复杂度。
还可以二分来找和\(di\)相加大于0的最小的\(dj\)。
//https://www.cnblogs.com/shuitiangong/
#include<set>
#include<map>
#include<list>
#include<stack>
#include<queue>
#include<cmath>
#include<cstdio>
#include<cctype>
#include<string>
#include<vector>
#include<climits>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define endl ‘\n‘
#define rtl rt<<1
#define rtr rt<<1|1
#define lson rt<<1, l, mid
#define rson rt<<1|1, mid+1, r
#define zero(a) memset(a, 0, sizeof(a))
#define INF(a) memset(a, 0x3f, sizeof(a))
#define IOS ios::sync_with_stdio(false)
#define _test printf("==================================================\n")
using namespace std;
typedef long long ll;
typedef pair<int, int> P;
typedef pair<ll, ll> P2;
const double pi = acos(-1.0);
const double eps = 1e-7;
const ll MOD = 998244353;
const int INF = 0x3f3f3f3f;
template<typename T> void read(T &x){
x = 0;char ch = getchar();ll f = 1;
while(!isdigit(ch)){if(ch == ‘-‘)f*=-1;ch=getchar();}
while(isdigit(ch)){x = x*10+ch-48;ch=getchar();}x*=f;
}
const int maxn = 2e5+10;
int a[maxn];
int main(void) {
int n;
scanf("%d", &n);
for (int i = 0; i<n; ++i)
scanf("%d", &a[i]);
for (int i = 0, b; i<n; ++i) {
scanf("%d", &b);
a[i] -= b;
}
sort(a, a+n);
ll ans = 0; int l = 0, r = n-1;
while(l<r) {
while(l<r && a[l]+a[r]<=0) ++l;
if (l>=r) break;
ans += r-l;
--r;
}
printf("%lld\n", ans);
return 0;
}
原文地址:https://www.cnblogs.com/shuitiangong/p/12567779.html
时间: 2024-10-05 22:37:14