思路: 错误思路:
因为ijk之间是没有关系的,只要找到三个数组之间递增的关系即可
我们可以给前两个数组分别用cnt计数,再对其进行前缀和,即可求解
#include<iostream>
using namespace std;
const int N = 1e5 + 10;
int n;
int a[N], b[N], c[N];
int cnta[N], cntb[N];
int main()
{
scanf("%d", &n);
for(int i=0; i<n; i++) scanf("%d%d%d", &a[i], &b[i], &c[i]);
for(int i=0; i<n; i++)
{
cnta[a[i]]++;
cntb[b[i]]++;
}
for(int i=0; i<n; i++)
{
if(i)
{
cnta[i] += cnta[i-1];
cntb[i] += cntb[i-1];
}
}
for(int i=0; i<n; i++)
return 0;
}
正解一: 排序 + 二分
#include<iostream>
#include<algorithm>
using namespace std;
const int N = 1e5 + 10;
typedef long long LL;
int n;
int a[N], b[N], c[N];
int cnta[N], cntb[N];
int findLast(int x)
{
int l = 0, r = n-1;
while(l < r)
{
int mid = l + r + 1>> 1;
if(a[mid] >= x) r = mid -1;
else l = mid;
}
if(a[l] >= x) return -1;
return l;
}
int findfirst(int x)
{
int l = 0, r = n-1;
while(l < r)
{
int mid = l + r >> 1;
if(c[mid] <= x) l = mid + 1;
else r = mid;
}
if(c[l] <= x) return n;
return l;
}
int main()
{
scanf("%d", &n);
for(int i=0; i<n; i++) scanf("%d", &a[i]);
for(int i=0; i<n; i++) scanf("%d", &b[i]);
for(int i=0; i<n; i++) scanf("%d", &c[i]);
sort(a, a+n);
sort(b, b+n);
sort(c, c+n);
LL res = 0;
for(int i=0; i<n; i++)
{
LL x = findLast(b[i]) + 1;
LL y = n - findfirst(b[i]);
//cout<<x<<" "<<y<<endl;
res += x*y;
}
cout << res << endl;
return 0;
}