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 数据:
当有多个元素相等的时候,只去掉了一个元素,导致计算错误。如果将 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
此贴结