求助CDQ板子
查看原帖
求助CDQ板子
282080
RefreshinglyNaive楼主2021/7/20 16:10
#include <bits/stdc++.h>
#define N 100005
#define int long long
using namespace std;
int n,m,sum[N],tot;
int lowbit(int x){ return x&(-x); }
struct query{
	int a,b,c,f,g;
}q[N];
void add(int x,int C){
	while(x<=n){
		sum[x]+=C;
		x+=lowbit(x);
	}
}
int qsum(int x){
	int res=0;
	while(x){
		res+=sum[x];
		x-=lowbit(x);
	}
	return res;
}
bool cmp1(query &a,query &b){ return a.a<b.a; }
bool cmp2(query &a,query &b){ return a.b>b.b; }
bool cmp3(query &a,query &b){ return a.c<b.c; }
bool cmp4(query &a,query &b){ return a.a>b.a; }
bool cmp5(query &a,query &b){ return a.b<b.b; }
void solve(int l,int r){
	if(l==r) return;
	int mid=(l+r)>>1;
	solve(l,mid); solve(mid+1,r);
	sort(q+l,q+mid+1,cmp2); sort(q+mid+1,q+r+1,cmp2);
	int pos=l;
	for(int i=mid+1;i<=r;i++){
		while(pos<=mid&&q[pos].b>q[i].b){
			add(q[pos].c,1); pos++;
		}q[i].f+=qsum(m+tot)-qsum(q[i].c); 
	}
	for(int i=l;i<pos;i++) add(q[i].c,-1);
}
void cdq(int l,int r){
	if(l==r) return;
	int mid=(l+r)>>1;
	cdq(l,mid); cdq(mid+1,r);
	sort(q+l,q+mid+1,cmp5); sort(q+mid+1,q+r+1,cmp5);
	int pos=l;
	for(int i=mid+1;i<=r;i++){
		while(pos<=mid&&q[pos].b<q[i].b){
			add(q[pos].c,1); pos++;
		}q[i].g+=qsum(m+tot)-qsum(q[i].c); 
	}
	for(int i=l;i<pos;i++) add(q[i].c,-1);
}
signed main(){
	int x,ans;
	while(cin>>n>>m){
		ans=0;
		for(int i=1;i<=n;i++){
			cin>>x;
			q[i].a=i; q[i].b=x; q[i].c=0;
			ans+=i-1-qsum(x);
			add(x,1);
		}
		memset(sum,0,sizeof(sum));
		for(int i=1;i<=m;i++) cin>>x,q[x].c=i;
		tot=0;
		for(int i=1;i<=n;i++) if(q[i].c==0) q[i].c=(++tot)+m;
		sort(q+1,q+n+1,cmp1);
		solve(1,n);
		sort(q+1,q+n+1,cmp4);
		cdq(1,n);
		sort(q+1,q+n+1,cmp3);
		for(int i=1;i<=m;i++){
			cout<<ans<<endl;
			ans=ans-q[i].f-q[i].g;
		}
	}
	return 0;
}
2021/7/20 16:10
加载中...