题目大意:有一个人有n个光盘,从下到上依次是n-1,现在给出操作m,意思是要把光盘m拿出来并放到最上面,并问操作前,关盘m上面有多少个光盘

解题思路:用两个数组,pos数组纪录每个数所在的位置,t数组纪录这个数前面有多少个光盘

将第n个放在第一个,第n-1个放在第2个,依此类推,然后更新t数组,这样的话,如果要求编号为m的光盘上面有多少个光盘,就可以直接用sum(maxn-1) - sum(pos[m])
然后,每次更新的时候,先更新pos[m]后面的,依此-1,然后再将pos[m]设置为当前这些光盘的最后面,再更新pos[m]后面的

#include<cstdio>
#include<cstring>
const int maxn = 100010 << 2;
int t[maxn], pos[maxn], n, m;

int lowbit(int x) {
    return x&(-x);
}

void Update(int x, int d) {
    while(x < maxn) {
        t[x] += d;
        x += lowbit(x);
    }
}

int sum(int x) {
    int ans = 0;
    while(x > 0) {
        ans += t[x];
        x -= lowbit(x);
    }
    return ans;
}

void init() {
    for(int i = 1; i <= n; i++) {
        Update(i,1);
        pos[i] = n - i + 1;
    }
}

int main() {
    int test;
    scanf("%d", &test);
    while(test--) {
        scanf("%d%d", &n, &m);
        memset(t,0,sizeof(t));
        init();
        int cur = n, x;
        for(int i = 0; i < m; i++) {
            scanf("%d", &x);
            int ans = sum(maxn-1) - sum(pos[x]);
            printf("%d%c", ans, i == m - 1 ? '\n':' ');
            Update(pos[x],-1);
            pos[x] = ++cur;
            Update(pos[x],1);
        }
    }
    return 0;
}