AcWing:. 241 Loulan Totem (Fenwick tree reverse order)

After completing the assigned tasks, the West came to 314 west of the ancient city of Loulan.

According to legend, a long time ago on this land (even earlier than the ancient city of Loulan) lived two tribes, a tribe worship knife ( 'V'), a tribe worship spade ( '∧'), and they were with V shape to represent ∧ Totem respective tribes.

In the following Kroraina 314 West discovered huge mural, murals labeled a point N, which was found by measuring the horizontal position of the points N and vertical positions are pairwise disjoint.

West 314 that the information contained in the mural with the relative position of the N points, and therefore might coordinates are provided ( . 1 , Y . 1 ) , ( 2 , Y 2 ) , ... , ( n- , Y n- ) (. 1 , y1), (2, y2 ), ..., (n, yn), wherein Y 1 Y1 ~ Y n Yn are arranged in a 1 to n.

314 west intend to study the mural contains a number of totem.

If the three points ( I , Y I ) , ( J , Y J ) , ( K , Y K ) (I, Yi), (J, YJ), (K, YK) meet . 1 I < J < K n and Y I > Y J , Y J < Y K 1≤i <J <k ≤ n and yi> yj, yj <yk, V is said three points constitute a totem;

If the three points ( I , Y I ) , ( J , Y J ) , ( K , Y K ) (I, Yi), (J, YJ), (K, YK) meet . 1 I < J < K n and Y I < Y J , Y J > Y K 1≤i <J <k ≤ n and yi <yj, yj> yk, three dots ∧ called totem;

314 west want to know the number of the n points in two tribal totem.

Therefore, you need to write a program to find the number and the number of ∧ V's.

Input Format

A first line number n.

The second row is a number n, representing the Y . 1 , Y 2 , ... , Y n- Y1, Y2, ..., Yn.

Output Format

Two numbers separated by a space intermediate, followed by the number and the number of V-∧.

data range

For all the data, the n- 200000 n≤200000, and the output will not exceed the answer int64.

Sample input:

5
1 5 3 2 4

Sample output:

3 4

 

Solution: from 1 ~ n seek down again reverse order greater than the current value of the number of records to the array leftup, smaller than the current number of records to the array leftdown. Similarly, n ~ 1 again against the reverse order from the request number is larger than the current record to the array rightup, smaller than the current number of records to the array rightdown. Then once again need only to traverse the array, the current center point value, and quantity "v", that is, (the number in front of the number larger than the current value leftup [i] * value larger than the current rear rightup [i]). Similarly seeking "^" number.

 

#include <iostream>
#include <cstdio>

using namespace std;

typedef long long ll;

const int maxn = 2e5+7;

int n;
int arr[maxn], tree[maxn];
ll leftup[maxn], rightup[maxn], leftdown[maxn], rightdown[maxn];

int lowbit(int x) {
    return x & (-x);
}

ll ask(int x) {
    ll res = 0;
    while(x >= 1) {
        res += tree[x];
        x -= lowbit(x);
    }
    return res;
}

void add(int x) {
    while(x <= n) {
        tree[x]++;
        x += lowbit(x);
    }
}

int main() {
    scanf("%d", &n);
    for(int i = 1; i <= n; i++) {
        scanf("%d", &arr[i]);
    }
    for(int i = 1; i <= n; i++) {
        leftdown[i] = ask(arr[i] - 1);
        leftup[i] = ask(n) - ask(arr[i]);
        add(arr[i]);
    }
    for(int i = 1; i <= n; i++) {
        tree[i] = 0;
    }
    for(int i = n; i >= 1; i--) {
        rightdown[i] = ask(arr[i] - 1);
        rightup[i] = ask(n) - ask(arr[i]);
        add(arr[i]);
    }
    ll ans1 = 0, ans2 = 0;
    for(int i = 1; i <= n; i++) {
        ans1 += leftup[i] * rightup[i];
        ans2 += leftdown[i] * rightdown[i];
    }
    cout << ans1 << " " << ans2 << endl;
    return 0;
}

 

Guess you like

Origin www.cnblogs.com/buhuiflydepig/p/11404025.html