前言
开学,练习开始了ohh
传送门 :
题意
给定三个三元组,求满足 A [ i ] < B [ j ] < C [ k ] A[i]<B[j]<C[k] A[i]<B[j]<C[k] 的组合数量
思路
朴素做法显然是三层循环直接枚举的,
1
e
5
∗
1
e
5
∗
1
e
5
1e5*1e5*1e5
1e5∗1e5∗1e5
但是我们发现我们可以通过 枚举
b
b
b数组, 然后二分寻找
a
[
]
,
b
[
]
a[],b[]
a[],b[]数组中满足条件的个数
然后通过乘法原理直接相乘即可优化
n
∗
l
o
g
n*log
n∗log
这个题目应该也可以使用树状数组作,暂做保留
CODE
#include <iostream>
#include <vector>
#include <map>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std;
#define IOS ios::sync_with_stdio(false);
#define CIT cin.tie(0);
#define COT cout.tie(0);
#define ll long long
#define x first
#define y second
#define pb push_back
#define endl '\n'
#define all(x) (x).begin(),x.end()
typedef priority_queue<int,vector<int>,greater<int>> Pri_m;
typedef pair<int,int> pii;
typedef vector<int> VI;
map<int,int> mp;
const int N = 1e5+10;
int a[N],b[N],c[N];
int n;
void solve()
{
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+1+n);
sort(b+1,b+1+n);
sort(c+1,c+1+n);
ll ans = 0 ;
//如果遍历 b数组的话 那么就是要找 a[]比他最小的最大的那个数
//c[]是找比他最大的最小的那个数
for(int i = 1;i<=n;i++){
int cl = 0 ;
int l = 1 , r = n;
while(l<r){
int mid = l+r+1>>1;
if(a[mid] < b[i]) l = mid;
else r = mid-1;
}
if(a[l] >= b[i]) continue;
cl = l ;
l = 1, r = n;
while(l<r){
int mid = l+r>>1;
if(c[mid] > b[i]) r = mid;
else l = mid+1;
}
if(c[l] <= b[i]) continue;
ans+= cl*(n-l+1)*1ll;
}
cout<<ans<<endl;
}
/**mYHeart is my algorithm**/
int main()
{
//int t;cin>>t;while(t -- )
solve();
return 0;
}