给定三个整数数组
A=[A1,A2,…AN],
B=[B1,B2,…BN],
C=[C1,C2,…CN],
请你统计有多少个三元组 (i,j,k) 满足:
1≤i,j,k≤N
Ai<Bj<Ck
输入格式
第一行包含一个整数 N。
第二行包含 N 个整数 A1,A2,…AN。
第三行包含 N 个整数 B1,B2,…BN。
第四行包含 N 个整数 C1,C2,…CN。
输出格式
一个整数表示答案。
数据范围
1≤N≤105,
0≤Ai,Bi,Ci≤105
输入样例:
3
1 1 1
2 2 2
3 3 3
输出样例:
27
思路 就枚举b[i] 看看a[i]中有多少个数小于b[i],在看看c[i]中有多少个数大于b[i],让他俩相乘即可,这里用到乘法原理
//前缀和算法
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int a[N],b[N],c[N];
int s[N],cnt[N];
long long res;
int ac[N],cc[N];//ac[i]表示a数组中用多少个数小于b[i],cc[i]表示c数组中有多少个数大于b[i];
int n;
int main(){
cin >> n;
for(int i=0;i<n;i++) cin >> a[i],a[i]++;//+1防止下面出现负的下标
for(int i=0;i<n;i++) cin >> b[i],b[i]++;
for(int i=0;i<n;i++) cin >> c[i],c[i]++;
for(int i=0;i<n;i++) cnt[a[i]]++; //比如cnt[6]=2,它就表示a数组中有2个数为6;
for(int i=1;i<N;i++) s[i]=s[i-1]+cnt[i];//s[8]=3,就表示CNT数组的前缀和,前8个数的和为3,
//也就是说a数组中小于等于8的数有3个,
for(int i=0;i<n;i++) ac[i]=s[b[i]-1]; //比如b[i]=8,b[i]-1=7,s[7]就表示a数组中小于等于7的数有几个
memset(s,0,sizeof s);
memset(cnt,0,sizeof cnt);
for(int i=0;i<n;i++) cnt[c[i]]++;
for(int i=1;i<N;i++) s[i]=s[i-1]+cnt[i];
for(int i=0;i<n;i++) cc[i]=s[N-1]-s[b[i]];
for(int i=0;i<n;i++) res+=(long long)ac[i]*cc[i];
cout << res;
return 0;
}
二分也能做,挺简单的
#include<bits/stdc++.h>
using namespace std;
#define int long long
//先排序,然后预处理一下看b中的第bi个元素在a中有多少个比它小的,
//同理,预处理一下c中第ci个元素在b中有多少个比它小的然后相乘再累加即可
const int N=1e5+10;
int n;
int a[N],b[N],c[N];
int cntb[N],cntc[N];//cntb[i]=j 表示 a中有j个元素比b中的第i个元素小
// cntc[i]=j 表示 c中有j个元素比b中的第i个元素大
//我们要找的是在b中第i个元素有多少个c中的元素比它大,即找到大于它的最小值
signed main(){
cin >> n;
for(int i=1;i<=n;i++){
cin >> a[i];
}
for(int i=1;i<=n;i++){
cin >> b[i];
}
for(int i=1;i<=n;i++){
cin >> c[i];
}
sort(a+1,a+n+1);
sort(b+1,b+n+1);
sort(c+1,c+n+1);
for(int i=1;i<=n;i++){
int l=1,r=n;
while(l<r){
int mid=(l+r+1)>>1;
if(b[i]>a[mid]){
l=mid;
}
else {
r=mid-1;
}
}
if(a[l]>=b[i]){
cntb[i]=0;
}
else cntb[i]=l;
// cout << cntb[i] << " ";
}
// cout << endl;
for(int i=1;i<=n;i++){
int l=1,r=n;
while(l<r){
int mid=l+r>>1;
if(b[i]<c[mid]){
r=mid;
}
else {
l=mid+1;
}
}
if(b[i]>=c[l]) cntc[i]=0;
else cntc[i]=n-l+1;
// cout << cntc[i] << " ";
}
// cout << endl;
int res=0;
for(int i=1;i<=n;i++){
res+=cntb[i]*cntc[i];
}
cout << res;
return 0;
}