暴力
//暴力
#include<iostream>
using namespace std;
int n;
#define N 100010
int a[N];
int b[N];
int c[N];
int res;
int main()
{
cin >> n;
for(int j = 0; j <n;j++) scanf("%d",&a[j]);
for(int j = 0; j <n;j++) scanf("%d",&b[j]);
for(int j = 0; j <n;j++) scanf("%d",&c[j]);
for(int i = 0; i < n; i++)
{
for(int j = 0; j < n; j ++)
{
for(int k = 0; k < n;k++)
{
if( a[i] < b[j] && b[j] < c[k])
res++;
}
}
}
cout << res << endl;
return 0;
}
排序+二分,直接用二分找左右的两个模板 求出即可
//枚举B后,A,C的方案数相乘就确定了
#include<iostream>
#include<algorithm>
using namespace std;
int n;
#define N 100010
int a[N];
int b[N];
int c[N];
long long res;
//二分查找法
int left_find(int left,int right,int target,int num[])
{
while( left < right)
{
int mid = (right + left) / 2;
if(num[mid] == target)
right = mid;
else if( num[mid] > target)
right = mid;
else if( num[mid] < target)
left = mid + 1;
}
return left ;
}
int right_find(int left,int right,int target,int num[])
{
while( left < right)
{
int mid = (right + left) / 2;
if(num[mid] == target)
left = mid+1;
else if( num[mid] > target)
right = mid;
else if( num[mid] < target)
left = mid + 1;
}
// return left-1;
return left; //比target大的位置起始坐标
}
int main()
{
cin >> n;
for(int j = 0; j <n;j++) scanf("%d",&a[j]);
sort(a,a+n);
// for(int j = 0; j <n;j++) cout << a[j] << " ";
// cout << endl;
for(int j = 0; j <n;j++) scanf("%d",&b[j]);
sort(b,b+n);
for(int j = 0; j <n;j++) scanf("%d",&c[j]);
sort(c,c+n);
// cout << left_find(0,n,3,a) << endl;
// cout << (right_find(0,n,7,a) ) << endl;
//遍历b[i],找出a中小于b[i]的个数,找出c中大于b[i]的个数
for(int i = 0; i < n; i++)
{
long long num_a = left_find(0,n,b[i],a);
long long num_c = n - right_find(0,n,b[i],c);
res += (num_a*num_c);
}
cout << res << endl;
return 0;
}
前缀和
//暴力
// #include<iostream>
// using namespace std;
// int n;
// #define N 100010
// int a[N];
// int b[N];
// int c[N];
// int res;
// int main()
// {
// cin >> n;
// for(int j = 0; j <n;j++) scanf("%d",&a[j]);
// for(int j = 0; j <n;j++) scanf("%d",&b[j]);
// for(int j = 0; j <n;j++) scanf("%d",&c[j]);
// for(int i = 0; i < n; i++)
// {
// for(int j = 0; j < n; j ++)
// {
// for(int k = 0; k < n;k++)
// {
// if( a[i] < b[j] && b[j] < c[k])
// res++;
// }
// }
// }
// cout << res << endl;
// return 0;
// }
// //2、二分+排序
// //枚举B后,A,C的方案数相乘就确定了
// #include<iostream>
// #include<algorithm>
// using namespace std;
// int n;
// #define N 100010
// int a[N];
// int b[N];
// int c[N];
// long long res;
// //二分查找法
// int left_find(int left,int right,int target,int num[])
// {
// while( left < right)
// {
// int mid = (right + left) / 2;
// if(num[mid] == target)
// right = mid;
// else if( num[mid] > target)
// right = mid;
// else if( num[mid] < target)
// left = mid + 1;
// }
// return left ;
// }
// int right_find(int left,int right,int target,int num[])
// {
// while( left < right)
// {
// int mid = (right + left) / 2;
// if(num[mid] == target)
// left = mid+1;
// else if( num[mid] > target)
// right = mid;
// else if( num[mid] < target)
// left = mid + 1;
// }
// // return left-1;
// return left; //比target大的位置起始坐标
// }
// int main()
// {
// cin >> n;
// for(int j = 0; j <n;j++) scanf("%d",&a[j]);
// sort(a,a+n);
// // for(int j = 0; j <n;j++) cout << a[j] << " ";
// // cout << endl;
// for(int j = 0; j <n;j++) scanf("%d",&b[j]);
// sort(b,b+n);
// for(int j = 0; j <n;j++) scanf("%d",&c[j]);
// sort(c,c+n);
// // cout << left_find(0,n,3,a) << endl;
// // cout << (right_find(0,n,7,a) ) << endl;
// //遍历b[i],找出a中小于b[i]的个数,找出c中大于b[i]的个数
// for(int i = 0; i < n; i++)
// {
// int num_a = left_find(0,n,b[i],a);
// int num_c = n - right_find(0,n,b[i],c);
// res += (long long) (num_a*num_c);
// }
// cout << res << endl;
// return 0;
// }
//3、前缀和
//枚举B后,A,C的方案数相乘就确定了
#include<iostream>
#include<algorithm>
using namespace std;
int n;
#define N 100010
int a[N],cnt_a[N],S_a[N];
int b[N];
int c[N],cnt_c[N],S_c[N];
long long res;
int main()
{
cin >> n;
for(int j = 0; j <n;j++)
{
scanf("%d",&a[j]);
cnt_a[ a[j] ]++; //统计数组出现的次数
}
for(int j = 0; j <n;j++)
scanf("%d",&b[j]);
for(int j = 0; j <n;j++)
{
scanf("%d",&c[j]);
cnt_c[ c[j] ]++;
}
S_a[0] = cnt_a[0];
for(int j = 1; j <N;j++) //这里得从大N遍历,因为是从0-N所有出现的数
{
S_a[j] = S_a[j-1] + cnt_a[ j ];
}
S_c[0] = cnt_c[0];
for(int j = 1; j <N;j++)
{
S_c[j] = S_c[j-1] + cnt_c[ j ];
}
for(int i = 0; i < n; i++)
{
long long num_a = S_a[ b[i] - 1];
long long num_c = n - S_c[ b[i] ];
res += num_a*num_c;
}
cout << res << endl;
return 0;
}