您的位置:首页 > 其它

[bzoj3295][Cqoi2011]动态逆序对

2017-04-20 10:28 513 查看
来自FallDream的博客,未经允许,请勿转载,谢谢。

对于序列A,它的逆序对数定义为满足i<j,且Ai>Aj的数对(i,j)的个数。给1到n的一个排列,按照某种顺序依次删除m个元素,你的任务是在每次删除一个元素之前统计整个序列的逆序对数。

n<=100000 m<=50000

呃我感觉我中毒了 看到这道题第一个想法就是对询问分块

建出主席树,然后把操作压到栈里面,然后每次查询都遍历这个栈,计算答案。然后当操作达到一定数量的时候重建主席树。

块的大小取大约$\sqrt{nlogn}$比较优秀 复杂度$O(m(k+logn)+\frac{n}{k}nlogn)$

当然更靠谱的做法是cdq分治,这道题其实就是一道三维偏序 先对时间排序,然后在分治的时候对x排序,用树状数组/线段树处理y维即可。

复杂度$O(nlog^{2}n)$

询问分块

#include<iostream>
#include<cstdio>
#include<algorithm>
#define ll long long
#define MN 100000
#define N 131072
using namespace std;
inline int read()
{
int x = 0 , f = 1; char ch = getchar();
while(ch < '0' || ch > '9'){ if(ch == '-') f = -1;  ch = getchar();}
while(ch >= '0' && ch <= '9'){x = x * 10 + ch - '0';ch = getchar();}
return x * f;
}

int n,m,T[N*2+5],ans=0,s[MN+5];ll Ans[MN+5],pos[MN+5];
struct ques{int kind,t,x,y;}q[MN+5],b[MN+5];

int query(int l,int r)
{
int sum=0;
for(l+=N-1,r+=N+1;l^r^1;l>>=1,r>>=1)
{
if(~l&1) sum+=T[l+1];
if( r&1) sum+=T[r-1];
}
return sum;
}

void renew(int x,int ad)
{
T[x+=N]+=ad;
for(x>>=1;x;x>>=1)T[x]=T[x<<1]+T[x<<1|1];
}
bool cmpX(ques x,ques y){return x.x<y.x;}
void solve(int l,int r)
{
if(l>=r) return;
int mid=l+r>>1;
for(int i=l;i<=r;i++) b[i]=q[i],b[i].kind=(i<=mid)?1:2;
sort(b+l,b+r+1,cmpX);
for(int i=l;i<=r;i++)
if(b[i].kind==1) renew(b[i].y,1);
else Ans[b[i].t]+=query(b[i].y,n);
for(int i=l;i<=r;i++)
if(b[i].kind==1)renew(b[i].y,-1);
for(int i=r;i>=l;i--)
if(b[i].kind==1)renew(b[i].y,1);
else Ans[b[i].t]+=query(1,b[i].y);
for(int i=l;i<=r;i++)
if(b[i].kind==1)renew(b[i].y,-1);
solve(l,mid);
solve(mid+1,r);
}
bool cmpT(ques x,ques y){return x.t<y.t;}
int main()
{
n=read();m=read();int tot=n;
for(int i=1;i<=n;i++)pos[s[i]=read()]=i;
for(int i=1;i<=m;i++)q[pos[read()]].t=tot--;
for(int i=1;i<=n;q[i].x=i,q[i].y=s[i],++i)if(!q[i].t) q[i].t=tot--;
sort(q+1,q+n+1,cmpT);
solve(1,n);ll sum=0;
for(int i=1;i<=n;i++) sum+=Ans[i];
for(int i=n;i>n-m;i--) printf("%lld\n",sum),sum-=Ans[i];
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: