LA 5902 Movie collection (树状数组)

本文介绍了一道ACM竞赛题目的解决方案,题目要求对于n个堆叠的物品进行查询和移动操作,并实时更新物品的位置。通过使用动态数组重新编号的方法,结合线段树和差分更新技巧,有效地解决了物品位置的查询与更新问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=27885

题意:有n个物品从上到下放置,并且标号1~n,有n次查询,每次查询标号为x的物品现在的位置(0~n,即该物品上面有多少个物品),同时将该物品取出放到第0号位置。

分析:将1~n件物品重新编号,1~n标为n~1,每次拿出一件物品x,再将其重新编号,如果是第一次拿出就标为n+1.....依次递增,然后将之前的编号删掉,插入新的编号。

代码:

#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
const int maxn = 2e5+6;
int tree[maxn],lowbit[maxn],num[maxn];
void getlowbit()
{
	for(int i=1;i<maxn;i++)
		lowbit[i]=i&-i;
}
void update(int x,int v)
{
	for(int i=x;i<maxn;i+=lowbit[i])
		tree[i]+=v;
}
int query(int x)
{
	int ret(0);
	for(int i=x;i>0;i-=lowbit[i])
		ret+=tree[i];
	return ret;
}
int main()
{
	getlowbit();
	int ncase,n,i,j,q,cur,x;
	scanf("%d",&ncase);
	while(ncase--)
	{
		scanf("%d%d",&n,&q);
		memset(tree,0,sizeof(tree));
		for(i=1;i<=n;i++)
		{
			num[i]=n-i+1;
			update(i,1);
		}
		cur=n;
		for(i=1;i<=q;i++)
		{
			scanf("%d",&x);
			printf("%d",n-query(num[x]));
			if(i!=q)
				printf(" ");
			update(num[x],-1);
			num[x]=++cur;
			update(num[x],1);
			
		}
		printf("\n");
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值