题意:
解法:
题目即求有多少个三元组,max和min的差值不超过d,
将三个数组中的元素混起来排序,
设三个元素为x,y,z,且x<y<z,
考虑枚举z=p[i],维护一个最小的指针l,满足p[i]和p[l]的差值<=d,
此时若选择z=p[i],那么可以在[l,i-1]中任选其他两种数,
设[l,i-1]中与z不同类型的两种数有cnt1和cnt2种,那么答案累加cnt1*cnt2.
区间中有多少种t类型的数,可以通过预处理前缀和快速计算.
code:
#include <bits/stdc++.h>
#define int long long
#define PI pair<int,int>
using namespace std;
const int maxm=2e6+5;
int a[maxm];
int b[maxm];
int c[maxm];
int q,w,e,d;
PI p[maxm];
int sum[maxm][3];
bool cmp(PI a,PI b){
return a.first<b.first;
}
signed main(){
ios::sync_with_stdio(0);
cin>>q>>w>>e>>d;
int num=0;
for(int i=1;i<=q;i++){
int x;cin>>x;
p[++num]={x,0};
}
for(int i=1;i<=w;i++){
int x;cin>>x;
p[++num]={x,1};
}
for(int i=1;i<=e;i++){
int x;cin>>x;
p[++num]={x,2};
}
sort(p+1,p+1+num,cmp);
for(int i=1;i<=num;i++){
for(int j=0;j<3;j++)sum[i][j]=sum[i-1][j];
sum[i][p[i].second]++;
}
int ans=0;
int l=1;
for(int i=1;i<=num;i++){
while(p[i].first-p[l].first>d)l++;
int x,y;
if(p[i].second==0)x=1,y=2;
else if(p[i].second==1)x=0,y=2;
else x=0,y=1;
int cnt1=sum[i][x]-sum[l-1][x];
int cnt2=sum[i][y]-sum[l-1][y];
ans+=cnt1*cnt2;
}
cout<<ans<<endl;
return 0;
}