1. 程式人生 > >Lost Cows

Lost Cows

link

題目大意

每次找到沒有被詢問過的第k小的數。共$n$個詢問,答案不超過$n$。$(n\leq 10^5)$

試題分析

其實是一個線段樹的板子,然後用一下主席樹的思想就行。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
inline int read(){
    int f=1,ans=0;char c=getchar();
    while(c<'
0'||c>'9'){if(c=='-')f=-1;c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+c-'0';c=getchar();} return f*ans; } const int N=1000001; int sum[N<<2],st[N<<2],kth[N<<2],n; void build(int k,int l,int r){ sum[k]=(r-l+1); if(l==r) return; int mid=l+r>>1
; build(k<<1,l,mid),build(k<<1|1,mid+1,r); return; } int query(int k,int l,int r,int kth){ if(l==r) return l; int mid=l+r>>1; if(sum[k<<1]>=kth) return query(k<<1,l,mid,kth); return query(k<<1|1,mid+1,r,kth-sum[k<<1]); }
void add(int k,int l,int r,int x,int y,int w){ sum[k]+=w; if(l==r) return; int mid=l+r>>1; if(x<=mid) add(k<<1,l,mid,x,y,w); if(mid<y) add(k<<1|1,mid+1,r,x,y,w); return; } int main(){ n=read();kth[1]=1; for(int i=2;i<=n;i++) kth[i]=read()+1; build(1,1,n); for(int i=n;i>=1;i--){ st[i]=query(1,1,n,kth[i]); add(1,1,n,st[i],st[i],-1); } for(int i=1;i<=n;i++) printf("%d\n",st[i]); }
View Code