玄关求条,动态开点 RE 50

P1908 逆序对

Z_kazuha @ 2025-01-11 11:31:51

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=5e5+5;
int n,sum=1e9+7,ans,cnt=1;
struct node{int l,r,ls,rs,p;}tree[N<<2];
void pushup(int p){
    tree[p].p=tree[tree[p].ls].p+tree[tree[p].rs].p;
}
void update(int p,int L){
    if(tree[p].l==tree[p].r&&tree[p].l==L){
        tree[p].p++;
        return;
    }
    int mid=(tree[p].l+tree[p].r)>>1;
    if(!tree[p].ls){
        tree[p].ls=++cnt;
        tree[cnt].l=tree[p].l,tree[cnt].r=mid;
    }
    if(!tree[p].rs){
        tree[p].rs=++cnt;
        tree[cnt].l=mid+1,tree[cnt].r=tree[p].r;        
    }
    if(L<=mid)update(tree[p].ls,L);
    else update(tree[p].rs,L);
    pushup(p);
}
int query(int p,int L,int R){
    if(p==0)return 0;
    if(tree[p].l>=L&&tree[p].r<=R){
        return tree[p].p;
    }
    int mid=(tree[p].l+tree[p].r)>>1;
//  if(L<=mid)res+=query(tree[p].ls,L,R);
//  if(R>mid)res+=query(tree[p].rs,L,R);
//  return res;
    if(R<=mid)return query(tree[p].ls,L,R);
    else if(L>mid)return query(tree[p].rs,L,R);
    else{
        return query(tree[p].ls,L,mid)+query(tree[p].rs,mid+1,R);
    } 
}
signed main(){
    ios::sync_with_stdio(false);
    cin.tie(0),cout.tie(0);
    cin>>n;
    tree[1].l=1,tree[1].r=sum;
    for(int i=1;i<=n;i++){
        int x;
        cin>>x;
        update(1,x);
        ans+=query(1,x+1,sum);
    }
    cout<<ans;
    return 0;
}

by 2022dyx @ 2025-01-11 11:48:46

空间开小了,动态开点线段树要 O(n\log n) 的空间。另外,开够了之后会 MLE,所以这题只能老老实实离散化只有用正常的线段树


by Z_kazuha @ 2025-01-11 11:51:13

@2022dyx

ok 谢谢


by light_searcher @ 2025-01-11 12:07:17

@2022dyx 不会 MLE


|