code:
#include <cstdio>
#include <string>
#include <algorithm>
#define N 200007
#define ll long long
using namespace std;
namespace IO {
void setIO(string s)
{
string in=s+".in";
string out=s+".out";
freopen(in.c_str(),"r",stdin);
// freopen(out.c_str(),"w",stdout);
}
};
int n,tot;
int rt[N<<1];
ll ans1,ans2,ans;
struct node {
int val,ls,rs;
}t[N*40];
void update(int &x,int l,int r,int p)
{
if(!x) x=++tot;
++t[x].val;
if(l==r) return;
int mid=(l+r)>>1;
if(p<=mid) update(t[x].ls,l,mid,p);
else update(t[x].rs,mid+1,r,p);
}
int merge(int x,int y)
{
if(!x||!y) return x+y;
int now=++tot;
t[now].val=t[x].val+t[y].val;
// t[x].val+=t[y].val;
ans1+=(ll)t[t[x].rs].val*t[t[y].ls].val;
ans2+=(ll)t[t[y].rs].val*t[t[x].ls].val;
t[now].ls=merge(t[x].ls,t[y].ls);
t[now].rs=merge(t[x].rs,t[y].rs);
return now;
}
int build()
{
int x;
scanf("%d",&x);
if(!x)
{
int lson=build();
int rson=build();
ans1=ans2=0;
rt[x]=merge(lson,rson);
ans+=min(ans1,ans2);
}
else update(rt[x],1,n,x);
return rt[x];
}
int main()
{
// IO::setIO("input");
int i,j;
scanf("%d",&n);
build();
printf("%lld\n",ans);
return 0;
}
本文介绍了一种离线动态树状数组的数据结构实现,通过使用区间合并和更新操作,解决了一类区间统计问题。文章详细展示了代码实现,包括初始化、更新和合并操作,以及如何在合并过程中进行区间统计,最终输出最小的统计结果。
355

被折叠的 条评论
为什么被折叠?



