The Number of groups in the sequence that meet the requirements of Ai <Aj> Ak and I <j <k HIT 2275 Number sequence, aj2275
Http://acm.hit.edu.cn/hoj/problem/view? Id = 2275
Number sequence
|
Source: SCU Programming Contest 2006 Final |
|
Time limit: 1 sec |
|
Memory limit: 64 M |
Submitted: 1632, Accepted: 440
Given a number sequence which has N element (s), please calculate the number of different collocation for three number Ai, Aj, Ak, which satisfy that Ai <Aj> Ak and I <j <k.
Input
The first line is an integer N (N <= 50000 ). the second line contains N integer (s): A1, A2 ,..., an (0 <= Ai <= 32768 ).
Output
There is only one number, which is the number of different collocation.
Sample Input
51 2 3 4 1
Sample Output
6
- Submit
- Status
- Statistic
- Solution
- Discuss
- Print
Solution 1
1. process each data in the forward order by following the steps below: Use a tree array to count the number of records smaller than it and record it in the tmp array; From then on, the data is updated to a larger number. I want to explain this: The subscript of the tree array is the size of the number. Because it comes in order, I <j <k is guaranteed. Then we can know the number of smaller ones.
2. Clear the c array and then perform reverse processing. Then we can know how many of them are smaller than this number.
3. multiply and sum two pieces of data in each number, and store the output using long.
# Include <stdio. h> # include <iostream> # include <string. h >#include <algorithm> # define MAXN 50010 # define MAXM 32771 int a [MAXN]; int c [MAXM]; int tmp [MAXN]; int n; int lowbit (int x) {return x & (-x);} void add (int x, int ad) {while (x <MAXM) {c [x] + = ad; x + = lowbit (x) ;}} int sum (int x) {int res = 0; while (x> 0) {res + = c [x]; x-= lowbit (x);} return res;} int main () {while (scanf ("% d", & n )! = EOF) {long ans = 0; memset (tmp, 0, sizeof (tmp); memset (c, 0, sizeof (c )); for (int I = 1; I <= n; I ++) {scanf ("% d", & a [I]); a [I] ++; tmp [I] = sum (a [I]-1); // note that it is strictly greater than add (a [I], 1);} memset (c, 0, sizeof (c); for (int I = n; I> = 1; I --) {ans + = (long) sum (a [I]-1) * tmp [I]; // (long) is very important, but it has never been added. Add (a [I], 1);} printf ("% lld \ n", ans);} return 0 ;}
Solution 2
1. The question requires a total of matching methods, meeting the requirements of Ai <Aj> Ak. And I j k is different
2. We open two tree arrays. The first one is updated when input. Then we maintain the second tree array while enumerating Aj. For AI, it is to sum up in the second tree array.
Then, the number of AKs can be obtained through the first tree array, and the result can be multiplied.
Code:
#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;const int MAXN = 50010;int n , num[MAXN];int treeNumOne[MAXN];int treeNumTwo[MAXN];int lowbit(int x){ return x&(-x);}int getSum(int *arr , int x){ int sum = 0; while(x){ sum += arr[x]; x -= lowbit(x); } return sum;}void add(int *arr , int x , int val){ while(x < MAXN){ arr[x] += val; x += lowbit(x); }}long long getAns(){ if(n < 3) return 0; long long ans = 0; add(treeNumTwo , num[1] , 1); for(int i = 2 ; i < n ; i++){ int x = getSum(treeNumTwo , num[i]-1); int y = getSum(treeNumOne , num[i]-1); add(treeNumTwo , num[i] , 1); ans += (x)*(y-x); } return ans;}int main(){ while(scanf("%d" , &n) != EOF){ memset(treeNumOne , 0 , sizeof(treeNumOne)); memset(treeNumTwo , 0 , sizeof(treeNumTwo)); for(int i = 1 ; i <= n ; i++){ scanf("%d" , &num[i]); num[i]++; add(treeNumOne , num[i] , 1); } printf("%lld\n" , getAns()); } return 0;}
Copyright Disclaimer: This article is an original article by the blogger and cannot be reproduced without the permission of the blogger.