UVALive 5902 - Movie collection(BIT)

题目链接 https://cn.vjudge.net/problem/UVALive-5902

【题意】
给你一个长度为n的序列,刚开始序列从前到后分别为1,2,3…n,之后有若干次如下操作
每次选中一个元素x,统计序列中在x前面的元素有多少个,然后把x放到第一位

【输入格式】
多组输入,第一行为数据组数T. 之后每组数据第一行有两个整数n,m(n,m<=1e5)代表序列长度和操作次数,下一行有m个1~n之间的整数代表每次要对那个元素进行操作

【输出格式】
对每组数据,输出每次操作中排在当前元素前面的元素有多少个,用空格隔开

【思路】
BIT的简单应用,首先可以把元素的位置向右做一个偏移,然后用一个pos数组记录每个元素所处的位置,对应位置的BIT下标置为1,然后每次操作时,取出一个元素x,那么它前面的元素个数就是sum(pos[x]-1),之后就把x处的值重新赋值为0,在最前面找一处位置放入x同时更新pos数组即可

#include<bits/stdc++.h>
using namespace std;

const int maxn=200050;
const int pian=100005;

int n,m;
int bit[maxn],len;
int pos[maxn];

void add(int i,int x){
    while(i<=len){
        bit[i]+=x;
        i+=i&-i;
    }
}

int sum(int i){
    int ans=0;
    while(i){
        ans+=bit[i];
        i-=i&-i;
    }
    return ans;
}

int main(){
    int T;
    scanf("%d",&T);
    while(T--){
        scanf("%d%d",&n,&m);
        len=n+pian;
        memset(bit,0,sizeof(bit));
        for(int i=1;i<=n;++i){
            pos[i]=i+pian;
            add(pos[i],1);
        }
        int cur=pian;
        for(int i=1;i<=m;++i){
            int x;
            scanf("%d",&x);
            printf("%d%c",sum(pos[x]-1),i==m?'\n':' ');
            add(pos[x],-1);
            pos[x]=cur--;
            add(pos[x],1);
        }
    }
    return 0;
}
posted @ 2018-08-13 10:18  不想吃WA的咸鱼  阅读(128)  评论(0编辑  收藏  举报