[POI2007]TET-Tetris Attack

如果两个相同的数之间有x个未匹配的数,那么肯定要经过x次交换,所以与 [JLOI2013]删除物品类似,只要不做无效交换,交换数是一定的。
对于方案来讲,交换的位置是对于堆底的,所以当两个物品删除后,需要记录一个已被删去的物品的个数,输出位置时注意减去已被删去的物品的个数。
#include <bits/stdc++.h>
#define lowbit(x) x&(-x)
using namespace std;
const int N=1e6+5;
int n,dis,del,ans,tot;
int a[N],vis[N],c[N],sta[N];

inline void change(int x,int v)
{
    
    
	while (x<=2*n)
	{
    
    
		c[x]+=v;
		x+=lowbit(x);
	}
}
inline int query(int x)
{
    
    
	int res=0;
	while (x)
	{
    
    
		res+=c[x];
		x-=lowbit(x);
	}
	return res;
}

int main(){
    
    
	scanf("%d",&n);
	for (register int i=1; i<=2*n; ++i) scanf("%d",&a[i]);
	for (register int i=1; i<=2*n; ++i)
	{
    
    
		if (!vis[a[i]]) vis[a[i]]=i,change(i,1);
		else	
		{
    
    
			dis=query(i)-query(vis[a[i]]);
			ans+=dis;
			int now=i-1;
			while (dis) sta[++tot]=now-del,now--,dis--;
			del+=2;
			change(vis[a[i]],-1);
		}
	}
	printf("%d\n",ans);
	for (register int i=1; i<=tot; ++i) printf("%d\n",sta[i]);
return 0;	
}

猜你喜欢

转载自blog.csdn.net/Dove_xyh/article/details/107840965