bzoj3192 [JLOI2013]删除物品 树状数组

每次操作一定是直接换到当前最大的,所以相当于来回移动求移动次数

把两个栈拼在一起就是一个队列,然后就直接查询个数+删点统计答案,用树状数组


码:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<map>
using namespace std;
int n,v[100005],n1,n2,a[100005],lin[100005],i,wz[100005],zz,l,r;
long long daan;
map<int ,int >ma;
int lowbit(int o)
{
	return o&(-o);
}
void jia(int wz)
{
  for(;wz<=n;wz+=lowbit(wz))
  v[wz]++;  	
}void jian(int wz)
{
  for(;wz<=n;wz+=lowbit(wz))
  v[wz]--;  	
}
int cha(int wz)
{
	int ans=0;
  for(wz;wz>0;wz-=lowbit(wz))ans+=v[wz];
  return ans;	
}
int main()
{
scanf("%d%d",&n1,&n2);n=n1+n2+1;
for(i=n1;i>=1;i--)
{
	scanf("%d",&a[i]);ma[a[i]]=i;lin[i]=a[i];
 jia(i);
}	
ma[0]=n1+1;
for(i=n1+2;i<=n1+n2+1;i++)
{jia(i);
	scanf("%d",&a[i]);ma[a[i]]=i;lin[i]=a[i];
}		
zz=n1+1;
	sort(lin+1,lin+1+n);
	for(i=n;i>=2;i--)
	{
		int mb=ma[lin[i]];
		l=mb;r=zz;
		if(l>r)swap(l,r);
		int jl=cha(r-1)-cha(l);
		daan+=jl;
		jian(mb);
		zz=mb;	
	}
	printf("%lld",daan);
}


猜你喜欢

转载自blog.csdn.net/haobang866/article/details/79277096