【动态整体kth 权值BIT】 Buy Tickes

传送门

题意

给定一个 \(N\),表示排队的总人数,每个人有 \(P_{i}\) 表示他进入队列时的位置以及 \(V_{i}\) 表示他的编号,确定最终的队列顺序,按照每个人的编号给出。

数据范围

\(1\leq N\leq 2\times 10^{5}\)
\(0\leq V_{i} \leq 32767\)
\(0\leq P_{i}\leq i-1\)

题解

同谜一样的牛,只不过编号是给定的,最后一个人的位置是一定确定的,从后往前做即可,找到当前还没选的

Code

#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,n) for(int i=a;i<n;i++)
#define per(i,a,n) for(int i=n-1;i>=a;i--)
#define fi first 
#define se second 
typedef pair<int,int> pii;

const int N=2e5+10;
int a[N],c[N];
pii p[N];
int q[N];
int n;
int lowbit(int x) {
    return x&(-x);
}
void add(int x,int d){
    for(int i=x;i<=n;i+=lowbit(i))
        c[i]+=d;
}
int ask(int x){
    int res=0;
    for(int i=x;i;i-=lowbit(i))
        res+=c[i];
    return res;
}
int main(){
    while(cin>>n){
        memset(c,0,sizeof c);
        rep(i,1,n+1) cin>>p[i].fi>>p[i].se;
        rep(i,1,n+1) add(i,1);

        per(i,1,n+1){
            int x=p[i].fi+1;
            int l=1,r=n;
            while(l<r){
                int mid=l+r>>1;
                if(ask(mid)>=x)
                    r=mid;
                else l=mid+1;
            }
            q[l]=p[i].se;
            add(l,-1);
        }
        rep(i,1,n+1) printf("%d ",q[i]);
        puts("");
    }
}

posted @ 2020-05-20 22:05  Hyx'  阅读(150)  评论(0)    收藏  举报