zoukankan      html  css  js  c++  java
  • ●POJ 2828 Buy Tickets

    题链:

    http://poj.org/problem?id=2828

    题解:

    线段树。

    逆向考虑这个过程。最后的序列S共有n个元素。

    先看最后一个人,如果他插入到第i位,那么他最终的位置就是当前序列S的第i号位置,然后把这个位置去掉,得到新序列S'。

    再按上面的操作确定倒数第二个人的位置:

    如果他插入到第j位,那么他就在新序列S'的第j个位置。

    。。。。。。以此类推,可以确定出所有人的位置。

    可以用线段树去确定位置。

    代码:

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #define MAXN 200050
    using namespace std;
    struct People{
    	int p,d;
    }P[MAXN];
    struct SGT{
    	int ls[MAXN<<1],rs[MAXN<<1],siz[MAXN<<1],sz,rt;
    	void build(int &u,int l,int r){
    		u=++sz; siz[u]=r-l+1;
    		if(l==r) return;
    		int mid=(l+r)/2;
    		build(ls[u],l,mid);
    		build(rs[u],mid+1,r);
    	}
    	void Reset(int n){
    		sz=rt=0;
    		build(rt,1,n);
    	}
    	int Modify(int u,int l,int r,int k){
    		siz[u]--; if(l==r) return l;
    		int mid=(l+r)/2;
    		if(k<=siz[ls[u]]) return Modify(ls[u],l,mid,k);
    		else return Modify(rs[u],mid+1,r,k-siz[ls[u]]);
    	}
    }DT;
    int ANS[MAXN];
    int main(){
    	int n;
    	while(~scanf("%d",&n)){
    		DT.Reset(n);
    		for(int i=1;i<=n;i++) scanf("%d%d",&P[i].p,&P[i].d);
    		for(int i=n,p;i;i--){
    			p=DT.Modify(DT.rt,1,n,P[i].p+1);
    			ANS[p]=P[i].d;
    		}
    		for(int i=1;i<n;i++) printf("%d ",ANS[i]);
    		if(n) printf("%d
    ",ANS[n]);
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    个人任务
    个人任务。。
    个人任务。
    个人任务
    未来周计划(一)
    澡堂人数实时查询助手的NABC分析
    react 中的fragments
    数组
    如何区分对象、数组、null
    数组的并集,交集,差集的实现
  • 原文地址:https://www.cnblogs.com/zj75211/p/8365585.html
Copyright © 2011-2022 走看看