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\n");
        }
        else
        {
            for(int i=1;i<=n;i++)
                printf(" %d",ans[i]);
            printf("\n");
        }
    }
}
时间: 2024-08-05 21:37:56

HDU 5493 Queue 树状数组的相关文章

HDU Cow Sorting (树状数组)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2838 Cow Sorting Problem Description Sherlock's N (1 ≤ N ≤ 100,000) cows are lined up to be milked in the evening. Each cow has a unique "grumpiness" level in the range 1...100,000. Since grumpy cow

hdu 5193 分块 树状数组 逆序对

题意: 给出n个数,a1,a2,a3,...,an,给出m个修改,每个修改往数组的某个位置后面插入一个数,或者把某个位置上的数移除.求每次修改后逆序对的个数. 限制: 1 <= n,m <= 20000; 1 <= ai <= n 思路: 插入和删除用分块来处理,块与块之间用双向链表来维护,每一块用树状数组来求小于某个数的数有多少个. 外层可以使用分块维护下标,这样添加和删除元素的时候,也很方便,直接暴力.查找权值个数时,使用树状数组比较方便.内层通过树状数组维护权值. 每次更新即

HDU 5249 离线树状数组求第k大+离散化

KPI Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1160    Accepted Submission(s): 488 Problem Description 你工作以后, KPI 就是你的全部了. 我开发了一个服务,取得了很大的知名度.数十亿的请求被推到一个大管道后同时服务从管头拉取请求.让我们来定义每个请求都有一个重要值.我的

hdu 4000Fruit Ninja 树状数组

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2048    Accepted Submission(s): 805 Problem Description Recently, dobby is addicted in the Fruit Ninja. As you know, dobby is a free elf, so unlik

hdu 4455 Substrings(树状数组+递推)

题目链接:hdu 4455 Substrings 题目大意:给定一个长度为N的序列,现在有Q次询问,每次给定一个w,表示长度,输出序列中长度为w的连续子序列 的权值和.序列的权值表示序列中不同元素的个数. 解题思路:递推,先预处理处每个位置和前面相同的数据的最短距离P.dp[i]表示说长度为i子序列的权值和,dp[i+1] = dp[i] + v - c.v为[i+1~N]中P值大于i的个数,我们可以看作将长度为i的子序列长度向后增加1,那么v则为增加长度带来 的权值增加值,c则是最后一个长度为

POJ 2352 &amp;&amp; HDU 1541 Stars (树状数组)

一开始想,总感觉是DP,可是最后什么都没想到.还暴力的交了一发. 然后开始写线段树,结果超时.感觉自己线段树的写法有问题.改天再写.先把树状数组的写法贴出来吧. ~~~~~~~~~~~~~~~~~~~~~~~~ 树状数组不懂的去看刘汝佳的大白书,那个图画得很清楚. 题目大意:星星的坐标以y递增的顺序给出,这些点的左下方的点数代表这个点的级数,问0~N-1的级数有多少个?其实y根本木有用. 题目链接:http://poj.org/problem?id=2352 http://acm.hdu.edu

hdu 4031(树状数组+辅助数组)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4031 Attack Time Limit: 5000/3000 MS (Java/Others)    Memory Limit: 65768/65768 K (Java/Others) Total Submission(s): 1890    Accepted Submission(s): 554 Problem Description Today is the 10th Annual of "S

HDU 2689Sort it 树状数组 逆序对

Sort it Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 4110    Accepted Submission(s): 2920 Problem Description You want to processe a sequence of n distinct integers by swapping two adjacent s

HDU 2838 (DP+树状数组维护带权排序)

Reference: http://blog.csdn.net/me4546/article/details/6333225 题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2838 题目大意:每头牛有个愤怒值,每次交换相邻两个数进行升序排序,$cost=val_{1}+val_{2}$,求$\min \sum cost_{i}$ 解题思路: 按输入顺序DP: 第i的值val的最小cost=当前数的逆序数个数*val+当前数的逆序数和 相当于每次只