UVA 1513 Movie collection 树状数组

UVA 1513

题意:你有n个带有编号1到n的盘子叠在一块,编号小的在上面,编号大的在下面,你现在有q个操作,每次操作抽出一个盘子,求这个盘子的上面有几个盘子, 并且把这个盘子放在顶面。

思路:可用树状数组,每次抽出一个盘子,给这个盘子一个新的最大的下标值插入树状数组。

#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=200000+5;
int n,c[maxn],a[maxn],ans[maxn],cnt;
int low(int x)
{
	return x&(-x);
}
void add(int k,int value)
{
	while(k)
	{
		c[k]+=value;
		k-=low(k);
	}
}
void init()
{
	cnt=n;
	memset(c,0,sizeof(c));
	for(int i=1;i<=n;i++)
	{
		a[i]=n-i+1;
		add(a[i],1);
	}
}
int sum(int k)
{
	int res=0;
	while(k<maxn)
	{
		res+=c[k];
		k+=low(k);
	}
	return res;
}
int main()
{
	int T;
	scanf("%d",&T);
	while(T--)
	{
		int m,i,k,tot=0;
		scanf("%d%d",&n,&m);
		init();
		while(m--)
		{
			scanf("%d",&k);
			ans[++tot]=sum(a[k])-1;
			add(a[k],-1);
			a[k]=++cnt;
			add(a[k],1);
		}
		for(i=1;i<tot;i++)
		printf("%d ",ans[i]); 
		printf("%d\n",ans[tot]);
	}
}

猜你喜欢

转载自blog.csdn.net/ccsu_cat/article/details/80748197