hdu5493 线段树

来源:互联网 发布:足球比赛抽签软件 编辑:程序博客网 时间:2024/05/16 08:42

题目大意:n个人,知道每个人的身高,还有他前面或者后面比他高的人数。问原队列最小字典序的身高,不可能输出impossible。

思路:重点是想到线段树,找他前面或者后面的空位能不能有那么多,若不能则直接不可能。每次更新时找arr[i].num和n-i-arr[i].num的最小值去更新,保证字典序最小。


#include <iostream>#include <cstdio>#include <string>#include <cstring>#include <fstream>#include <algorithm>#include <cmath>#include <queue>#include <stack>#include <vector>#include <map>#include <set>#include <iomanip>using namespace std;#define maxn 100005#define MOD 1000000007#define mem(a , b) memset(a , b , sizeof(a))#define LL long long#define INF 1000000000struct T{    int l , r , val;}tree[maxn*3];struct node{    int h , num;}arr[maxn];int ans[maxn];bool cmp(node n1 , node n2){    return n1.h < n2.h;}void build(int root , int l , int r){    tree[root].l = l;    tree[root].r = r;    if(l == r)    {        tree[root].val = 1;        return;    }    int mid = (l + r)>>1;    build(root<<1 , l , mid);    build(root<<1|1 , mid + 1 , r);    tree[root].val = tree[root<<1].val + tree[root<<1|1].val;}void update(int root , int pos , int val){    if(tree[root].l == tree[root].r)    {        tree[root].val = 0;        ans[tree[root].l] = val;        return;    }    int mid = (tree[root].l+tree[root].r)>>1;    if(pos <= tree[root<<1].val) update(root<<1 , pos , val);    else update(root<<1|1 , pos - tree[root<<1].val , val);    tree[root].val = tree[root<<1].val + tree[root<<1|1].val;}int main(){    int n , t , k = 1;    scanf("%d" , &t);    while(t--)    {        scanf("%d" , &n);        mem(tree , 0);        for(int i = 1 ; i <= n ; i ++) scanf("%d %d" , &arr[i].h , &arr[i].num);        build(1 , 1 , n);        sort(arr + 1 , arr + n + 1 , cmp);        int flag = 0;        for(int i = 1 ; i <= n ; i ++)        {            int tmp = n - i - arr[i].num;            if(tmp < 0) {flag = 1 ;  break;}            if(arr[i].num <= tmp) update(1 , arr[i].num + 1 , arr[i].h);            else update(1 , tmp + 1 , arr[i].h);        }        printf("Case #%d: " , k++);        if(flag) printf("impossible\n");        else        {            for(int i = 1 ; i <= n ; i ++)            {                printf("%d" , ans[i]);                if(i != n) printf(" ");            }            printf("\n");        }    }    return 0;}


0 0
原创粉丝点击