1 条题解
-
2wdvxdr LV 8 MOD @ 2017-11-06 20:23:57
这道题我们需要计算的是有多少个数对\((i,j,k)\),满足\(A_i<B_j<C_k\),我们可以转换成求对于没一个\(j\)满足\(A_i<B_j\)和\(B_j<C_k\)的数量,根据乘法原理,答案就是这两个数相乘。
对于前\(60\%\)的数据,我们可以枚举每个\(B_j\),分别求\(A_i\),和\(C_k\)的数量,这样的做法时间复杂度是\(O(N^2)\)的。
对于\(100\%\)的数据这样做太慢了,我们可以先将\(A\)和\(B\)进行排序,再用二分查找来优化。
这样做时间复杂度是\(O(N log_2 N)\)的。
~~某人的\(O(N)\)做法其实也是\(O(N log_2 N)\),那个反着的前缀和应该管它叫后缀和吧。~~
#include<bits/stdc++.h> using namespace std; vector<int> A,B,C; long long n,ans; int main() { int temp; scanf("%lld",&n); for(int i=1;i<=n;i++) { scanf("%d",&temp); A.push_back(temp); } for(int i=1;i<=n;i++) { scanf("%d",&temp); B.push_back(temp); } for(int i=1;i<=n;i++) { scanf("%d",&temp); C.push_back(temp); } sort(A.begin(),A.end()); sort(C.begin(),C.end()); sort(B.begin(),B.end()); for(int i=0;i<n;i++) { int acnt = lower_bound(A.begin(),A.end(),B[i]) - A.begin(); int ccnt = upper_bound(C.begin(),C.end(),B[i]) - C.begin(); if(acnt >= 1&&ccnt!=n) ans += acnt * (n-ccnt); } cout << ans << endl; return 0; }
- 1
信息
- 难度
- 7
- 分类
- (无)
- 标签
- (无)
- 递交数
- 55
- 已通过
- 9
- 通过率
- 16%
- 上传者