uva 1513 Movie collection

来源:互联网 发布:哪里有淘宝店铺出租 编辑:程序博客网 时间:2024/06/07 10:33

题意:有一堆电影片碟,按1-n顺序排,有m次操作,每次询问第ai个电影片碟之前有多少个,然后将其抽出放在堆顶。
分析:树状数组,用一个数组记录每个编号的片碟现在所处的位置。每次移动就将这张片碟的num(位置)更新一下,将之前的num作废,以后查询也是用之后的num。

代码:
#include<iostream>#include <cstring>using namespace std;int n, m, num[100001], t[200001], l, r;//num:原数组;t:树状数组int lowbit(int x){    return x&(-x);}void update(int x, int p)//将第x个数加p{    while(x <= 200001)    {        t[x] += p;        x += lowbit(x);    }    return;}int sum(int k)//前k个数的和{    int ans = 0;    while(k > 0)    {        ans += t[k];        k -= lowbit(k);    }    return ans;}//int ask(int l, int r)//求l-r区间和//{//    return sum(r) - sum(l-1);//}int main(){    int T, x;    cin >> T;    while(T--)    {        cin>> n >> m;        memset(t, 0, sizeof(t));        memset(num, 0, sizeof(num));        for(int i = 1; i <= n; i++)        {            num[i] = n-i+1;            update(i, 1);        }        int cur = n;        bool first = true;        for(int i = 0; i < m; i++)        {            cin >> x;            if(first) first = false;            else cout << " ";            cout << n - sum(num[x]);//sum表示x当前片子的下面有多少个            update(num[x], -1);//上面的片子的下面的片子都减1            num[x] = ++cur;            update(num[x], 1);        }        cout << endl;    }    return 0;}


原创粉丝点击