原题
思路很nb,继续学习,加油加油加油!
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e5 + 10;
int cnt[N], s[N];
int a[N], b[N], c[N];
int n;
int as[N], cs[N];
ll ans;
//算法思路:利用cnt找到每个数出现过几次,然后利用前缀和数组s[i]记录下所有小于等于i的数出现的次数
//之后利用as[i]数组记录下在a中,小于等于b[i]的数出现过几次
//...cs[i]利用同等方法得出大于等于b[i]的数在c中出现了几次
//遍历i,让as[i]*cs[i]之和就是答案
int main()
{
scanf("%d", &n);
for(int i = 0; i < n; i ++ ){
scanf("%d", &a[i]);
a[i] ++ ;
}
for(int i = 0; i < n; i ++ ){
scanf("%d", &b[i]);
b[i] ++ ;
}
for(int i = 0; i < n; i ++ ){
scanf("%d", &c[i]);
c[i] ++ ;
}
//计算前缀和
for(int i = 0; i < n; i ++ ){
cnt[a[i]] ++ ;
}
for(int i = 1; i < N; i ++ ){
s[i] = s[i - 1] + cnt[i];//记录小于等于i的数出现了几次
}
for(int i = 0; i < n; i ++ ){
as[i] = s[b[i] - 1];
}
memset(cnt, 0, sizeof cnt);
memset(s, 0, sizeof s);
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 ++ ){
cs[i] = s[N - 1] - s[b[i]];
}
//as和cs在形成时就是和b[i]有关,所以这里直接遍历0~n就可以
for(int i = 0; i < n; i ++ ){
ans += (ll)as[i] * cs[i];
}
cout<<ans<<endl;
return 0;
}