题目
Snuke Festival的季节今年又来了。首先,林戈将举行仪式来召唤斯库克。对于仪式,他需要一个祭坛,由三部分组成,三个部分分别为一个:上部,中部和下部。
他对这三个类别中的每一个都有N个部分。第i个上部的尺寸是Ai,第i个中部的尺寸是Bi,第i个下部的尺寸是Ci。
要建造一个祭坛,中间部分的大小必须严格大于上部的大小,下部的大小必须严格大于中间部分的大小。另一方面,满足这些条件的任何三个部分可以组合形成祭坛。
Ringo可以建造多少个不同的祭坛?这里,当使用的三个部分中的至少一个不同时,认为两个祭坛是不同的。
约束
1≤N≤10 5
1≤Ai≤10 9(1≤i≤N)
1≤Bi≤10 9(1≤i≤N)
1≤Ci≤10 9(1≤i≤N)
的所有输入值是整数。
输入
输入由标准输入以下列格式给出:
N
A1 ... AN
B1 ... BN
C1 ... CN
输出
打印Ringo可以构建的不同祭坛的数量。
样例输入
1 5
2 4
3 6
样例输出
3
提示
可以建造以下三个祭坛:
上部:第一部分,中部:第一部分,下部:第一部分
上部:第一部分,中部:第一部分,下部:第二部分
上部:第1部分,中部:第2部分,下部:第2部分
题解
也就是说我们考虑这样的一个问题
建造的祭坛是严格递增的。
我们考虑中部 和 下部 的方案数。对其进行一个前缀和的操作。
那么我们可以对上部箱子/中部箱子进行同样的操作,对满足条件的中部箱子累加前缀和即可。
代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5+10;
ll arr[3][maxn];
ll val[maxn];
int n;
int main()
{
while(~scanf("%d",&n))
{
for(int i=0;i<3;i++) {
for(int j=0;j<n;j++) scanf("%lld",&arr[i][j]);
sort(arr[i],arr[i]+n);
}
ll res = 0;
for(int i=0;i<n;i++) {
val[i] = (ll)n - (upper_bound(arr[2],arr[2]+n,arr[1][i])-arr[2]);
//printf("%lld\n",val[i]);
if(i > 0) val[i] += val[i-1];
}
for(int i=0;i<n;i++) {
int pos = upper_bound(arr[1],arr[1]+n,arr[0][i])-arr[1];
res += val[n-1] - (pos > 0 ? val[pos-1] : 0);
}
printf("%lld\n",res);
}
return 0;
}