UVA 1513 - Movie collection(树状数组)

题目链接:点击打开链接

题意: 有编号1~n的n个影碟从上到下排列, 每次取一个影碟并把其放在最上面, 求每次取之前该影碟前面有多少个影碟。

取出影碟, 将该位置-1即可, 容易想到用树状数组来维护, 但是还要放到最前面。 其实解决方法很简单, 就是把数组开大一点, 前面留出足够大的空间, 不断更新位置即可。

细节参见代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<string>
#include<vector>
#include<stack>
#include<bitset>
#include<cstdlib>
#include<cmath>
#include<set>
#include<list>
#include<deque>
#include<map>
#include<queue>
#define Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)<(b)?(a):(b))
using namespace std;
typedef long long ll;
const double PI = acos(-1.0);
const double eps = 1e-6;
const int mod = 1000000000 + 7;
const int INF = 1000000000;
const int maxn = 200000 + 10;
int T,n,v,m,bit[maxn],pos[maxn>>1];
int sum(int x) {
    int ans = 0;
    while(x > 0) {
        ans += bit[x];
        x -= x & -x;
    }
    return ans;
}
void add(int x, int d) {
    while(x <= n + m) {
        bit[x] += d;
        x += x & -x;
    }
}
int main() {
    scanf("%d",&T);
    while(T--) {
        scanf("%d%d",&n,&m);
        memset(bit, 0, (n+m+1)*sizeof(bit[0]));
        int cnt = m;
        for(int i=1;i<=n;i++) {
            pos[i] = i+m;
            add(pos[i], 1);
        }
        for(int i=0;i<m;i++) {
            scanf("%d",&v);
            printf("%d%c", sum(pos[v]-1), i == m-1 ? '\n' : ' ');
            add(pos[v], -1);
            pos[v] = cnt--;
            add(pos[v], 1);
        }
    }
    return 0;
}
时间: 2024-08-07 14:22:40

UVA 1513 - 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 11423 - Cache Simulator(树状数组)

UVA 11423 - Cache Simulator 题目链接 题意:题目讲的大概就是几个cash,每次操作可以加入一个或一些数据,如果数据之前有就是hit,命中后的数据就不会消失,如果没有就miss,当容量超过cash容量时,就会把之前最早没命中的一个丢掉,每次START就执行这些命令,计算miss次数并输出 思路:由于最多就2^24的数据,所以可以开一个树状数组,每个位置表示第i个添加进去的数据,并且把每个数据对应的位置记录下来,下次如果添加到一个之前有的数据,就利用树状数组查询上一次到这

uva 1428 - Ping pong(树状数组)

题目链接:uva 1428 - Ping pong 题目大意:一条大街上住着n个乒乓球爱好者,经常组织比赛.每个人都有一个不同的能力值,每场比赛需要3个人,裁判要住在两个选手之间,并且能力值也要在选手之间,问说最多能举行多少场比赛. 解题思路:预处理出bi和ci分别表示说在1~i中能力值比第i个人小的人和i+1~n中能力值比第i个人小的.处理过程用树状数组维护即可. #include <cstdio> #include <cstring> #include <algorith

UVA 10909 - Lucky Number(树状数组)

UVA 10909 - Lucky Number 题目链接 题意:问一个数字能否由两个lucky num构造出来,lucky num根据题目中的定义 思路:利用树状数组找前k大的方法可以构造出lucky num的序列,然后每次查找n,就从n / 2开始往下查找即可 代码: #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int N = 2000001

Permutation UVA - 11525(值域树状数组,树状数组区间第k大(离线),log方,log)

Permutation UVA - 11525 看康托展开 题目给出的式子(n=s[1]*(k-1)!+s[2]*(k-2)!+...+s[k]*0!)非常像逆康托展开(将n个数的所有排列按字典序排序,并将所有排列编号(从0开始),给出排列的编号得到对应排列)用到的式子.可以想到用逆康托展开的方法.但是需要一些变化: for(i=n;i>=1;i--) { s[i-1]+=s[i]/(n-i+1); s[i]%=(n-i+1); } 例如:n=3时,3=0*2!+0*1!+3*0!应该变为3=1

uva 11525排列(树状数组 + 二分)

 现在给定k和n,要你按字典序输出 第n种排列的数列 而且题目给的 n是 n=S1(k-1)!+S2(k-2)!+...+Sk-1*1!+Sk*0!(0=<Si<=k-i), 我们可以知道si表示i后面有多少个比a[i]小的数,这样一来首先想到的就是set,但是set不能顺序访问,所以可以用树状数组,初始时置1,消除后置0,然后二分来求和为si + 1的位置 代码如下: #include<cstdio> #include<cstring> #include<c

uva 12356 Army Buddies 树状数组解法 树状数组求加和恰为k的最小项号 难度:1

Nlogonia is fighting a ruthless war against the neighboring country of Cubiconia. The Chief General of Nlogonia's Army decided to attack the enemy with a linear formation of soldiers, that would advance together until conquering the neighboring count

UVA - 1471 Defense Lines 树状数组/二分

                              Defense Lines After the last war devastated your country, you - as the king of the land of Ardenia - decided it washigh time to improve the defense of your capital city. A part of your forti?cation is a line of magetower

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 <c

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前面,取完