Algorithm Competition Getting Started Classic Training Guide (Blue Book) Ping pong (UVaLive4329) Tree Array

meaning of the title

In a sequence, if there are three numbers in ascending order or descending order, these three numbers can be regarded as being able to hold a match. Ask about the number of races.

ps. Ascending or descending order means that someone between two athletes can act as a referee, and both athletes are willing to play at the referee's home.

ideas

Young a 1 a_1a1To ai − 1 a_ {i-1}ai1Yes bi b_ibiNumber ratio ai a_iaismall, then i − 1 − bi i-1-b_ii1biNumber ratio ai a_iaibig. So we can record ai a_iaileft side than ai a_iaiSmall numbers and ai a_iaiRight than ai a_iaismall number.

Create two tree-like arrays, update the arrays while traversing the sequence, the second ii of the tree-like arraysi bit records the current ratioiiThe number of small numbers of i . lll array is traversed and updated in positive order, representingai a_iaileft side than ai a_iaismall number. Similarly, rrThe r array is reversed to the right thanai a_iaismall number.

答案即为 ∑ 1 n [ l i × ( n − i − r i ) + ( i − 1 − l i ) × r i ] \sum_{1}^{n} [l_i \times (n-i-r_i)+(i-1-l_i) \times r_i] 1n[li×(niri)+(i1li)×ri]

Accepted code

/*
 * @Autor: CofDoria
 * @Date: 2021-03-06 19:14:39
 * @LastEditTime: 2021-03-08 16:55:47
 */
#include <bits/stdc++.h>
using namespace std;

#define db double
#define ll long long
#define lowbit(x) (x & -x)
#define inf 0x3f3f3f3f
#define s(a, n) memset(a, n, sizeof(a))
#define debug(a) cout << '#' << a << '#' << '\n'
#define rep(l, a, b) for (register ll l = a; l < b; ++l)
#define per(l, a, b) for (register ll l = a; l >= b; --l)
#define _ios ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
#define _forit(i, c) \
    for (__typeof__((c).begin()) i = (c).begin(); i != (c).end(); ++i)

bool fi = true;
const unsigned long long MOD = 1e9 + 7;

inline ll gcd(ll a, ll b) {
    
     return (b == 0 ? a : gcd(b, a % b)); }

ll t, n, a[100005];
ll l[100005], r[100005];
ll ansl[100005], ansr[100005];
ll ans;
// vector<int> q;

void addl(int x) {
    
    
    while (x <= 100000) ++l[x], x += lowbit(x);
}

ll suml(int x) {
    
    
    ll cnt = 0;
    while (x) cnt += l[x], x -= lowbit(x);
    return cnt;
}

void addr(int x) {
    
    
    while (x <= 100000) ++r[x], x += lowbit(x);
}

ll sumr(int x) {
    
    
    ll cnt = 0;
    while (x) cnt += r[x], x -= lowbit(x);
    return cnt;
}

int main() {
    
    
    // freopen("in.txt", "r", stdin);
    // freopen("out.txt", "w", stdout);
    _ios;
    cin >> t;
    while (t--) {
    
    
        ans = 0;
        s(l, 0);
        s(r, 0);
        cin >> n;
        rep(i, 0, n) {
    
    
            cin >> a[i];
            ansl[i] = suml(a[i]);
            addl(a[i]);
        }
        per(i, n - 1, 0) {
    
    
            ansr[i] = sumr(a[i]);
            addr(a[i]);
            ans += ansr[i] * (i - ansl[i]) + ansl[i] * (n - 1 - i - ansr[i]);
        }
        cout << ans << '\n';
    }
    // fclose(stdin);
    // fclose(stdout);
    return 0;
}

Guess you like

Origin blog.csdn.net/qq_46144509/article/details/114537761