题目: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 <cstdio> #include <iostream> #include <cstring> using namespace std; const int maxn = 2e5+6; int tree[maxn],lowbit[maxn],num[maxn]; void getlowbit() { for(int i=1;i<maxn;i++) lowbit[i]=i&-i; } void update(int x,int v) { for(int i=x;i<maxn;i+=lowbit[i]) tree[i]+=v; } int query(int x) { int ret(0); for(int i=x;i>0;i-=lowbit[i]) ret+=tree[i]; return ret; } int main() { getlowbit(); int ncase,n,i,j,q,cur,x; scanf("%d",&ncase); while(ncase--) { scanf("%d%d",&n,&q); memset(tree,0,sizeof(tree)); for(i=1;i<=n;i++) { num[i]=n-i+1; update(i,1); } cur=n; for(i=1;i<=q;i++) { scanf("%d",&x); printf("%d",n-query(num[x])); if(i!=q) printf(" "); update(num[x],-1); num[x]=++cur; update(num[x],1); } printf("\n"); } return 0; }
时间: 2024-10-01 00:57:04