The n2 upper bound for any sorting algorithm is easy to obtain: just take two elements that are misplaced with respect to each other and swap them. Conrad conceived an algorithm that proceeds by taking not two, but three misplaced elements. That is, take three elements ai > aj > ak with i < j < k and place them in order ak, aj , ai. Now if for the original algorithm the steps are bounded by the maximum number of inversions n(n-1)/2 , Conrad is at his wits' end as to the upper bound for such triples in a given sequence. He asks you to write a program that counts the number of such triples.
Output the number of inverted triples.
Sample Input 1 3 1 2 3 Sample Input 2 4 3 3 2 1
Sample Output 1 0 Sample Output 2 2
以每一个数为中间的数,在它前面找一个比它大的数,在它后面找一个比它小的数就形成了一个inverted triples
那么题目就转化成了,求出每一个数前面有多少个数比它小,记为 ans1, 后面有多少个数比它大,记为 ans2。
然后 ans1*ans2 就是以这个数为中间的数的对应的 inverted triples的数目。
那么只要求出每一个数前面有多少数比它大,后面有多少个数比它小
依次记录后遍历相乘的结果即为所求。
注意:数据比较小,You can assume that all ai are in [1, n].
所以不用离散化。。。。比赛的时候求正序数对的时候各种离散化各种错思路一下就明确了,代码敲了一个小时还是各种错。
如此弱菜我还能说什么呢。
#include<stdio.h> #include<string.h> const int maxn = 1e5+10; int n; int a[maxn]; //记录每一个数 int c[maxn]; long long ans1[maxn]; long long ans2[maxn]; int lowbit(int x) { return x&(-x); } void add(int i) { while(i <= n) { c[i]++; i += lowbit(i); } } long long sum(int i) { long long ret = 0; while(i > 0) { ret += c[i]; i -= lowbit(i); } return ret; } int main() { while(scanf("%d", &n) != EOF) { memset(a, 0, sizeof(a)); //清空 memset(c, 0, sizeof(c)); memset(ans1, 0, sizeof(ans1)); memset(ans2, 0, sizeof(ans2)); for(int i = 1; i <= n; i++) scanf("%d", &a[i]); for(int i = 1; i <= n; i++) { ans1[i] = sum(n) - sum(a[i]); //计算出现在 a[i] 前面比 a[i] 大的数的个数:总数- <=a[i] 的数 add(a[i]); //插入当前数据 } memset(c, 0, sizeof(c)); //重新清零 for(int i = n; i >= 1; i--) //逆序插入 { ans2[i] = sum(a[i]-1); //计算出现在 a[i] 后面但是比 a[i] 小的数的个数 add(a[i]); //插入当前数据 } long long ans = 0; for(int i = 1; i <= n; i++) ans += ans1[i]*ans2[i]; //前面比它大*后面比它小 printf("%lld\n", ans); } return 0; }