UVA 1513 Movie collection

来源:互联网 发布:紫峰抢票软件下载 编辑:程序博客网 时间:2024/06/11 17:55

题意:有一些光盘,每张光盘上都有一个数字,将光盘从1~n放好,1放在最上面,然后每次选出一张光盘,先输出这张光盘上面有几张光盘,然后把这张光盘拿出来放在最上面

解题思路:树状数组.arr数组记录每张光盘所在的位置,首先初始化,将1光盘的位置初始化为n,同时要将这个空间开成2倍的,因为每次查询把光盘放在最上面时都是放在上面额外又开出的m个空间里。查询时找到光盘所在的位置,将它下面的光盘数求出来,用n一减就行了,然后把光盘删去(其实就是光盘所在位置上的光盘数为0了),将光盘放在最上面

代码:

#include <iostream>#include <algorithm>#include <cstring>#include <string>#include <cstdio>#include <cmath>using namespace std;const int maxn=100000*2+5;//要开出n+m的空间int bit[maxn],arr[maxn];int n,m;int lowbit(int x){    return (x&-x);}int sum(int i){    int s=0;    while(i>0)    {        s+=bit[i];        i-=lowbit(i);    }    return s;}void add(int i,int x){    while(i<maxn)    {        bit[i]+=x;        i+=lowbit(i);    }}int main(){    int t;    cin>>t;    while(t--)    {        memset(arr,0,sizeof(arr));        memset(bit,0,sizeof(bit));        cin>>n>>m;        for(int i=1;i<=n;i++)        {            arr[i]=n-i+1;            add(arr[i],1);//arr[i]这个位置上有1个光盘        }        int v;        for(int i=1;i<=m;i++)        {            cin>>v;            int under=sum(arr[v]);//arr[v]下面的光盘数            cout<<n-under;            if(i==m)cout<<endl;            else cout<<" ";            add(arr[v],-1);//将v所在的位置arr[v]删去(空出)            arr[v]=n+i;//把v放在最上面            add(arr[v],1);//v所在的新位置上的光盘个数为1        }    }    return 0;}


原创粉丝点击