这道题平衡树为什么会WA

P1908 逆序对

LinAY827 @ 2024-11-15 19:21:21

RT.

FHQ Treap做的,思路是每次添加一个元素的时候查询此时的排名,然后用当前元素个数减去排名累加到ans上。

求大佬解答qwq.

#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,ans,a,root,idx,ran;
struct node
{
    int l,r,val,key,size;
}tr[500005];
void pushup(int x)
{
    tr[x].size=tr[tr[x].l].size+tr[tr[x].r].size+1;
}
void split(int p,int v,int &x,int &y)
{
    if(!p)
    {
        x=y=0ll;
        return;
    }
    if(tr[p].val<=v)
    {
        x=p;
        split(tr[x].r,v,tr[x].r,y);
    }
    else
    {
        y=p;
        split(tr[y].l,v,x,tr[y].l);
    }
    pushup(p);
}
int merge(int x,int y)
{
    if(!x||!y)
        return x+y;
    if(tr[x].key<tr[y].key)
    {
        tr[x].r=merge(tr[x].r,y);
        pushup(x);
        return x;
    }
    else
    {
        tr[y].l=merge(x,tr[y].l);
        pushup(y);
        return y;
    }
}
int newnode(int v)
{
    tr[++idx].val=v;
    tr[idx].key=rand();
    tr[idx].size=1;
    return idx;
}
void insert(int v)
{
    int x,y,z;
    split(root,v,x,y);
    z=newnode(v);
    root=merge(merge(x,z),y);
}
void getrank(int v)
{
    int x,y;
    split(root,v-1,x,y);
    ran=tr[x].size+1;
    root=merge(x,y);
}
signed main()
{
    srand(time(0));
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>a;
        insert(a);
        getrank(a);
        if(i!=1)
            ans+=(i-ran);
    }
    cout<<ans;
    return 0;
}

by Hagasei @ 2024-11-15 19:29:00

@LinAY827

把 getrank 修改成

void getrank(int v)
{
    int x,y;
    split(root,v,x,y);
    ran=tr[x].size;
    root=merge(x,y);
}

原因是有重复元素的情况


by lrx___ @ 2024-11-15 19:29:04

Hack 数据:1,1,1

当有多个元素相等的时候,只去掉了一个元素,导致计算错误。如果将 getrank 改成如下就能通过。

void getrank(int v)
{
    int x,y;
    split(root,v,x,y);
    ran=tr[x].size;
    root=merge(x,y);
}

by LinAY827 @ 2024-11-15 19:37:18

@Hagasei

大佬,之前我写的一版就是去除了重复情况的,也是不对


by Hagasei @ 2024-11-15 19:39:06

@LinAY827 但是这么写就过了。你之前那个怎么写的??


by LinAY827 @ 2024-11-15 19:41:14

@Hagasei

抱一丝大佬,我刚刚看错了您的代码,过了,感谢大佬!!


by LinAY827 @ 2024-11-15 19:41:33

@lrx___

感谢大佬,过了


by LinAY827 @ 2024-11-15 19:41:51

此贴结


|