BZOJ 3295

http://www.lydsy.com/JudgeOnline/problem.php?id=3295

时光倒流,把删除操作变成添加操作

那么就有三个维度(大小,位置,时间)

逆序对满足

ai<aj && bi<bj && ci>cj

ai<aj && bi>bj && ci<cj

那么,这不就是三维偏序嘛

时间维排序处理

位置维cdq分治,归并排序处理

大小维树状数组维护

#include<cstdio>
#include<algorithm>
#define FOR(i,s,t) for(register int i=s;i<=t;++i)
#define ROF(i,s,t) for(register int i=s;i>=t;--i)
using namespace std;
typedef long long ll;
int n,m,tot;
const int N=100011;
struct node{
	int x,y,z;
}q[N],t[N];
int pos[N],a[N],v;
ll ans[N];
int bo[N];
namespace BIT{
	int tr[N];
	inline void add(int pos){for(;pos<=n;++tr[pos],pos+=pos&-pos);}
	inline int query(int pos){int ret=0;for(;pos;pos-=pos&-pos)ret+=tr[pos];return ret;}
	inline void del(int pos){for(;pos<=n;pos+=pos&-pos)if(tr[pos])tr[pos]=0;else break; }
};
using namespace BIT;
inline void cdq(int l,int r){
	if(l==r)return;
	int mid=(l+r)>>1;
	cdq(l,mid);cdq(mid+1,r);
	int idx1=l,idx2=mid+1;
	FOR(i,l,r)t[i]=q[(idx2>r||(idx1<=mid&&q[idx1].y<q[idx2].y))?idx1++:idx2++];
	FOR(i,l,r)q[i]=t[i];
	int all=0;
	FOR(i,l,r)
		if(q[i].x<=mid)add(q[i].z),++all;
		else ans[q[i].x]+=1ll*(all-query(q[i].z));
	FOR(i,l,r)del(q[i].z);
	ROF(i,r,l)
		if(q[i].x<=mid)add(q[i].z);
		else ans[q[i].x]+=1ll*query(q[i].z);
	ROF(i,r,l)del(q[i].z);
}
int main(){
	scanf("%d%d",&n,&m);
	FOR(i,1,n)scanf("%d",&v),pos[v]=i;
	FOR(i,1,m)scanf("%d",a+i),bo[a[i]]=1;
	FOR(i,1,n)if(!bo[i])q[++tot]=(node){tot,pos[i],i};
	ROF(i,m,1)q[++tot]=(node){tot,pos[a[i]],a[i]};
	cdq(1,n);
	FOR(i,1,n)ans[i]+=1ll*ans[i-1];
	ROF(i,n,n-m+1)printf("%lld\n",ans[i]); 
	return 0;
}

  

posted @ 2017-11-28 11:43  Stump  阅读(149)  评论(0编辑  收藏  举报