AcWing 1236. 递增三元组
考察:双指针 or 二分排序 or 前缀和
思路:
n<=105 n2的时间复杂度也会超时,所以我们只能枚举一个数,这就必须要利用乘法原理求得答案,已知题目要求 ai<bj<ck如果我们枚举aior ck可以发现无法省略其他层枚举,而我们枚举b,c与a就能利用乘法原理,找到小于bj与大于bj的数,两者相乘累加得到答案.
关于怎么找的问题,可采用的算法有:
- 双指针
- 二分排序
- 前缀和.设sum[i]数组,表示a or c中 小于 or 大于i的数出现多少次.
1 #include <iostream> 2 #include <cstring> 3 #include <algorithm> 4 using namespace std; 5 const int N = 100010; 6 typedef long long LL; 7 int a[N],b[N],c[N]; 8 LL ans; 9 int main() 10 { 11 int n; 12 scanf("%d",&n); 13 for(int i=1;i<=n;i++) scanf("%d",&a[i]); 14 for(int i=1;i<=n;i++) scanf("%d",&b[i]); 15 for(int i=1;i<=n;i++) scanf("%d",&c[i]); 16 sort(a+1,a+n+1); 17 sort(b+1,b+n+1); 18 sort(c+1,c+n+1); 19 for(int i=1;i<=n;i++) 20 { 21 int x = lower_bound(a+1,a+n+1,b[i])-a; 22 int y = upper_bound(c+1,c+n+1,b[i])-c; 23 ans+=(LL)(x-1)*(n+1-y); 24 } 25 printf("%lld\n",ans); 26 return 0; 27 }