【BZOJ】3295: [Cqoi2011]动态逆序对

时间:2022-06-23 10:59:41

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3295


mamaya,弱鸡xrdog终于会写树套树啦....

将树状数组中每一个节点看成一棵平衡树,支持$RANK$操作,每次删除一个数之前,支持查询位置在当前数之前权值比他大的有多少个,查询位置在当前数之后权值比他小的有多少个,再支持删除操作。

复杂度${O(nlogn^{2})}$,空间复杂度${O(nlogn)}$


 #include<iostream>
#include<ext/pb_ds/assoc_container.hpp>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<set>
using namespace std;
using namespace __gnu_pbds;
#define maxn 1001000
#define llg long long
#define yyj(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
llg n,m,d[maxn],ans,wz[maxn],v;
tree<llg,null_type,less<llg>,rb_tree_tag,tree_order_statistics_node_update>c[maxn]; //tree<llg,null_mapped_type,less<llg>,rb_tree_tag,tree_order_statistics_node_update>c[maxn]; //-----如果您的编译器版本较低(BZOJ)
llg cc[maxn];
inline llg lowbit(llg x){return x&-x;} void add(llg x,llg val) {while (x<=n) {c[x].insert(val);x+=lowbit(x);}} void del(llg x,llg val) {while (x<=n) c[x].erase(val),x+=lowbit(x);} void add_(llg x,llg val) {while (x<=n) cc[x]+=val,x+=lowbit(x);} llg sum_(llg x) {llg tot=; while (x>) tot+=cc[x],x-=lowbit(x); return tot;} llg sum(llg x,llg val)
{
llg tot=;
while (x>)
{
tot+=c[x].size();
llg xiao=c[x].order_of_key(val+);
tot-=xiao;
x-=lowbit(x);
}return tot;
} llg summ(llg x,llg val)
{
llg tot=;
while (x>)
{
tot+=c[x].order_of_key(val+);
x-=lowbit(x);
}
return tot;
} void init()
{
cin>>n>>m;
for (llg i=;i<=n;i++)
{
scanf("%lld",&d[i]);
wz[d[i]]=i;
ans+=sum_(n)-sum_(d[i]);
add_(d[i],);
add(i,d[i]);
} } void work()
{
llg x,da,xiao;
while (m--)
{
printf("%lld\n",ans);
scanf("%lld",&v);
x=wz[v];
da=sum(x,v);
xiao=summ(n,v)-summ(x,v);
ans-=da+xiao;
del(x,v);
}
} int main()
{
yyj("bzoj3295");
init();
work();
return ;
}