逆序对权值线段树动态开点MLE

P1908 逆序对

senak @ 2024-05-22 11:03:32

#include<iostream>
#include<vector>
#include<map>
#include<algorithm>
#define int long long
const int N = 1e9 + 7;
using namespace std;
const int M = 5e5 + 5;
struct node {
    int sum = 0;
    int l = 0, r = 0;
}tr[M * 30];
#define ls(x) (tr[x].l)
#define rs(x) (tr[x].r)
#define sum(x) tr[x].sum  
int tot = 1;
void pushup(int x) {
    sum(x) = sum(ls(x)) + sum(rs(x));
}
void pushdown(int x) {
    if (!ls(x))ls(x) = ++tot;
    if (!rs(x))rs(x) = ++tot;
}
void upd(int x, int l, int r, int pos, int k) {
    if (l == r) {
        sum(x) += k;
        return;
    }
    int mid = (l + r - 1) / 2;
    pushdown(x);
    if (pos <= mid)upd(ls(x), l, mid, pos, k);
    else upd(rs(x), mid + 1, r, pos, k);
    pushup(x);
}
int que(int x, int l, int r, int L, int R) {
    if (L <= l && r <= R)return sum(x);
    if (l > R || r < L)return 0;
    pushdown(x);
    int mid = (l + r - 1) / 2;
    return
        que(ls(x), l, mid, L, R) +
        que(rs(x), mid + 1, r, L, R);
}
void add(int pos, int k) {
    upd(1, 1, N, pos, k);
}
int que(int L, int R) {
    return que(1, 1, N, L, R);
}
void insert(int x) { 
    add(x, 1);
}
void solve() {
    int n; cin >> n;
    int ans = 0;
    for (int i = 1; i <= n; i++) {
        int  x; cin >> x;
        ans += que(x + 1, N);
        insert(x);
    }cout << ans << endl;
}
signed main() {
    ios::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    solve();
    return 0;
}

by senak @ 2024-05-22 11:38:37

数据加强后权值线段树动态加点是不是不行了


by THUD @ 2024-06-16 18:28:10

@senak 好像是的,我也MLE了 record\ 输出了一下一共要开1e7个节点,肯定得爆


|