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("
    ");
            }
        }
    }
  • 相关阅读:
    你说什么都不队 实验七 团队作业3:团队项目需求分析与原型设计
    你说什么都不队 实验六团队作业2:小型医疗机构诊疗管理系统
    你说什么都不队 实验五 团队作业1:软件研发团队组建与软件案例分析
    Java并发编程中的设计模式解析(二)一个单例的七种写法
    Java并发编程之ThreadGroup
    基于JVM原理、JMM模型和CPU缓存模型深入理解Java并发编程
    Java并发编程之线程安全、线程通信
    Java并发编程中的设计模式解析(一)
    Java并发编程之线程生命周期、守护线程、优先级、关闭和join、sleep、yield、interrupt
    Java并发编程之线程创建和启动(Thread、Runnable、Callable和Future)
  • 原文地址:https://www.cnblogs.com/qscqesze/p/4842600.html
Copyright © 2011-2022 走看看