LA 5902 Movie collection (树状数组)

题目: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;
}
时间: 2024-10-01 00:57:04

LA 5902 Movie collection (树状数组)的相关文章

UVa 1513 Movie collection (树状数组)

题意:给定给你一叠DV,编号1到n,1在最上面,n在最下面.然后现在给你m个操作,每次都指定一张CD,问要拿走这个CD需要挪走上面多少张CD,并且这个要拿走的CD放在这个叠CD的顶端. 析:这个题要倒着来做,我就是正着做的,太复杂了,因为每次操作后,都要再重新处理后面的数,时间复杂度太高. 如果是倒着做,每次只要更新后面的就好,不用管前面的数,因为前面的是不会影响到的. 代码如下: #pragma comment(linker, "/STACK:1024000000,1024000000&quo

Uva - 1513 Moive collection ( 模拟栈 + 树状数组基本操作 )

Uva - 1513 Moive collection ( 模拟栈 + 树状数组基本操作 ) 题意: 一个书架,原来所有的书都是按顺序摆好的,书的编号从1开始到n 操作: 取出一本书,统计在这本书之前有多少本书,统计完之后,将这本书放在书架的第一位. 如:  1 2 3 4 5取4   4 1 2 3 5 (取之前,有3本书在4前面,取完后,将4放在栈顶)取4   4 1 2 3 5 (取之前,有0本书在4前面,取完后,将4放在栈顶)取2   2 4 1 3 5 (取之前,有2本书在2前面,取完

BNUOJ-22868-Movie collection(树状数组)

Description Mr. K. I. has a very big movie collection. He has organized his collection in a big stack. Whenever he wants to watch one of the movies, he locates the movie in this stack and removes it carefully, ensuring that the stack doesn't fall ove

UVA 1513 Movie collection (树状数组+反向存储)

题意:给你n盘歌碟按照(1....n)从上到下放,接着m个询问,每一次拿出x碟,输出x上方有多少碟并将此碟放到开头 直接想其实就是一线段的区间更新,单点求值,但是根据题意我们可以这样想 首先我们倒着存  n--1,接着每次询问时把放碟子放到最后,这样我们要开一个映射数组映射每个碟子在哪个位置 其中我们需要使用树状数组维护每个绝对位置是否有碟子(有些碟子已经放到了后面了),再使用区间求和就好了 #include<set> #include<map> #include<queue

树状数组 + 位运算 LA 4013 A Sequence of Numbers

题目传送门 题意:n个数,两种操作,一是每个数字加x,二是查询& (1 << T) == 1 的个数 分析:因为累加是永远的,所以可以离线处理.树状数组点是c[16][M] 表示数字x%(1 << j) 后的数字pos,考虑第j位的个数.当询问时根据add不同的值不同的处理情况. #include <bits/stdc++.h> using namespace std; typedef long long ll; const int N = 1e5 + 5; c

树状数组 LA 4329 亚洲赛北京赛区题

复习下树状数组 还是蛮有意思的一道题: http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=501&page=show_problem&problem=4174 学到几点: 1.树状数组C[i]的构建,一则c[i]=s[i]-s[i-lowbit(i)];这是一直用的做法.如今学到一种新的,直接add(i,a[i]),(s[i]为a[1]到a[i]的和) 2.前缀和思想,

LA 4329(树状数组)

题目描述: N <tex2html_verbatim_mark>(3N20000) <tex2html_verbatim_mark>ping pong players live along a west-east street(consider the street as a line segment). Each player has a unique skill rank. To improve their skill rank, they often compete with

LA 4329 (树状数组) Ping pong

第一次写树状数组,感觉那个lowbit位运算用的相当厉害. 因为-x相当于把x的二进制位取反然后整体再加上1,所以最右边的一个1以及末尾的0,取反加一以后不变. 比如1000取反是0111加一得到1000,这样与运算以后不变 最右边的1左边部分取反,加一不会影响左半部分,所以与运算以后全部为0 对于这道题来说貌似不是很容易能联想到树状数组 注意题中说了每个人的技能值互不相同. 从左往右扫描每个a[i],另x[a[i]] = 1,然后统计x[1]...x[a[i]-1]的和就是第i个人左边技能值比

LA 4329(树状数组)

算法竞赛入门经典 p197 题目大意: 一条大街上住着n个乒乓球爱好者.常常比赛切磋技术.每一个人都有一个不同的技能值a[i].每场比赛须要3个人:两名选手,一名裁判.他们有个奇怪的约定,裁判必须住在两名选手之间,而裁判的能力值也必须在两名选手之间.问一共能组织多少种比赛. 分析:    如果a[1]到a[i-1]中小于a[i]的数有p[i].a[i+1]到a[n]中小于a[i]的数有s[i]个; 这样当i为裁判时可以组织的比赛数目为:p[i]*(n-i-s[i]) + (i-1-p[i])*s