zoukankan      html  css  js  c++  java
  • HDU 5493 Queue 树状数组

    Queue

    Time Limit: 1 Sec  

    Memory Limit: 256 MB

    题目连接

    http://acm.hdu.edu.cn/showproblem.php?pid=5493

    Description

    N people numbered from 1 to N are waiting in a bank for service. They all stand in a queue, but the queue never moves. It is lunch time now, so they decide to go out and have lunch first. When they get back, they don’t remember the exact order of the queue. Fortunately, there are some clues that may help.
    Every person has a unique height, and we denote the height of the i-th person as hi. The i-th person remembers that there were ki people who stand before him and are taller than him. Ideally, this is enough to determine the original order of the queue uniquely. However, as they were waiting for too long, some of them get dizzy and counted ki in a wrong direction. ki could be either the number of taller people before or after the i-th person.
    Can you help them to determine the original order of the queue?

    Input

    The first line of input contains a number T indicating the number of test cases (T≤1000).
    Each test case starts with a line containing an integer N indicating the number of people in the queue (1≤N≤100000). Each of the next N lines consists of two integers hi and ki as described above (1≤hi≤109,0≤ki≤N−1). Note that the order of the given hi and ki is randomly shuffled.
    The sum of N over all test cases will not exceed 106

    Output

    For each test case, output a single line consisting of “Case #X: S”. X is the test case number starting from 1. S is people’s heights in the restored queue, separated by spaces. The solution may not be unique, so you only need to output the smallest one in lexicographical order. If it is impossible to restore the queue, you should output “impossible” instead.

    Sample Input

    3
    3
    10 1
    20 1
    30 0
    3
    10 0
    20 1
    30 0
    3
    10 0
    20 0
    30 1

    Sample Output

    Case #1: 20 10 30
    Case #2: 10 20 30
    Case #3: impossible

    HINT

    题意

    给你一些人,每个人的身高都是不一样的

    然后再给你一个k,表示这个人的左边或者右边,有k个人比他高

    然后让你构造一个序列,满足这个条件

    题解:

    每个人其实可以站两个位置,不是左边就是右边

    你从小到大插入的话,那么剩下没插的位置都是比你大的

    你就插进去就好

    用树状数组/splay/treap维护一下就好了

    代码:

    //qscqesze
    #pragma comment(linker, "/STACK:1024000000,1024000000")
    #include <cstdio>
    #include <cmath>
    #include <cstring>
    #include <ctime>
    #include <iostream>
    #include <algorithm>
    #include <set>
    #include <bitset>
    #include <vector>
    #include <sstream>
    #include <queue>
    #include <typeinfo>
    #include <fstream>
    #include <map>
    #include <stack>
    typedef long long ll;
    using namespace std;
    //freopen("D.in","r",stdin);
    //freopen("D.out","w",stdout);
    #define sspeed ios_base::sync_with_stdio(0);cin.tie(0)
    #define maxn 200006
    #define mod 1000000007
    #define eps 1e-9
    #define e exp(1.0)
    #define PI acos(-1)
    #define lowbit(x) (x)&(-x)
    const double EP  = 1E-10 ;
    int Num;
    //const int inf=0x7fffffff;
    const ll inf=999999999;
    inline ll read()
    {
        ll x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    //*************************************************************************************
    int n,val1[maxn],val2[maxn];
    
    void add(int * vc,int u ,int v)
    {
        while(u <= n )
        {
            vc[u] += v;
            u += lowbit(u);
        }
    }
    
    int query(int * vc,int u)
    {
        int res=0;
        while(u)
        {
            res += vc[u];
            u -= lowbit(u);
        }
        return res;
    }
    
    int RankGet(int * vc,int k)
    {
        int L = 1 , R = n;
        while(L < R)
        {
            int mid = L + ((R-L)>>1);
            int res = query(vc,mid);
            //cout << "mid is " << mid << " res is " << res << endl;
            if(res == k) R = mid;
            else if(res < k) L = mid + 1;
            else R = mid - 1;
        }
        return L;
    }
    
    struct kkk
    {
        int x,y;
    };
    bool cmp(kkk aa,kkk bb)
    {
        return aa.x<bb.x;
    }
    kkk p[maxn];
    int ans[maxn];
    vector<int> v1,v2;
    int main()
    {
     //   freopen("in.txt","r",stdin);
        int t=read();
        for(int cas=1;cas<=t;cas++)
        {
            n=read();
            for(int i=1;i<=n;i++)
            {
                p[i].x=read(),p[i].y=read();
                p[i].y++;
            }
            sort(p+1,p+n+1,cmp);
            int flag=1;
            memset(val1,0,4*(n+2));memset(val2,0,4*(n+2));
            for(int i = 1 ; i <= n ; ++ i)
            {
                add(val1,i,1);
                add(val2,i,1);
            }
            //return 0;
            for(int i=1;i<=n;i++)
            {
                if(p[i].y>n-i+1)
                {
                    flag=0;
                    break;
                }
                int p1 = RankGet(val1,p[i].y);
                int p2 = n-RankGet(val2,p[i].y) + 1;
               // cout << "i is " << i << " p1 is " << p1 << " p2 is " << p2 << endl;
               // int p1=v1[p[i].y],p2=v2[p[i].y];
                if(p1<p2)
                {
                    ans[p1]=p[i].x;
                    add(val1,p1,-1);
                    add(val2,n-p1+1,-1);
                    //cout << "up delete " << p1 << " down delete " << n-p1 +1 << endl;
                    //v1.erase(v1.begin()+p[i].y);
                    //v2.erase(v2.begin()+n-i+2-p[i].y);
                }
                else
                {
                    ans[p2]=p[i].x;
                    add(val1,p2,-1);
                    add(val2,n-p2+1,-1);
                 //   cout << "up delete " << p2 << " down delete " << n-p2 +1 << endl;
                    //v2.erase(v2.begin()+p[i].y);
                    //v1.erase(v1.begin()+n-i+2-p[i].y);
                }
               // cout << endl;
            }
            printf("Case #%d:",cas);
            if(!flag)
            {
                printf(" impossible
    ");
            }
            else
            {
                for(int i=1;i<=n;i++)
                    printf(" %d",ans[i]);
                printf("
    ");
            }
        }
    }
  • 相关阅读:
    面试再问HashMap,求你把这篇文章发给他!
    Maven Nexus私库搭建及使用,你还不会吗?
    两年摸爬滚打 Spring Boot,总结了这 16 条最佳实践
    @Controller,@Service,@Repository,@Component你搞懂了吗?
    mysql 输出当前月所有日期与对应的星期
    mysql创建每月执行一次的event
    一个关于explain出来为all的说明及优化
    怎么快速了解自己的MySQL服务器
    Mysql查找所有项目开始时间比之前项目结束时间小的项目ID
    Device eth0 does not seem to be present,delaying initialization解决方法
  • 原文地址:https://www.cnblogs.com/qscqesze/p/4842600.html
Copyright © 2011-2022 走看看