hdu 5493 Queue treap实现将元素快速插入到第i个位置

input

T 1<=T<=1000

n 1<=n<=100000

h1 k1

h2 k2

... ...

hn kn

1<=hi<=1e9   0<=ki<=n-1

sum(n)<=1e6

hi!=hj(i!=j)

output

hi指第i个人的身高,ki指这个人前面或者后面比他高的人数

Case #cas: 输出可能的最小序列,没有输出impossible

做法:将所有人按身高排序,从高到低插入数组中,则插入到第i个人时,数组里所有人都比他高,用treap实现,每个人有两个位置可以插入,每次插入到小的位置

 1 #include <cstdio>
 2 #include <queue>
 3 #include <cstring>
 4 #include <iostream>
 5 #include <cstdlib>
 6 #include <algorithm>
 7 #include <vector>
 8 #include <map>
 9 #include <set>
10 #include <ctime>
11 #include <cmath>
12 #include <cctype>
13 #define MAX 100000
14 #define LL long long
15 int cas=1,T,first,a[MAX+10][2];
16 struct node
17 {
18     node*ch[2];
19     int r,v,sz;
20     void maintain() { sz=(ch[0]?ch[0]->sz:0)+(ch[1]?ch[1]->sz:0)+1; }
21 };
22 void rotate(node* &o,int d)
23 {
24     node*k=o->ch[d^1];o->ch[d^1]=k->ch[d];k->ch[d]=o;
25     o->maintain();k->maintain();o=k;
26 }
27 void insert(node* &o,int pos,int &x)
28 {
29     if(o==NULL)
30     {
31         o=new node();
32         o->ch[0]=o->ch[1]=NULL;
33         o->v=x;o->r=rand();
34         o->sz=1;
35         return;
36     }
37     o->sz++;        //易错,旋转时可能没旋转到该结点,导致没更新,所以在插入后要++
38     int d;
39     if(pos <= (o->ch[0]?o->ch[0]->sz:0)) d=0;
40     else { d=1;pos -= (o->ch[0]?o->ch[0]->sz:0)+1; }
41     insert(o->ch[d],pos,x);
42     if(o->ch[d]->r > o->r) rotate(o,d^1);
43 }
44 void read(node*u)
45 {
46     if(u==NULL) return;
47     read(u->ch[0]);
48     printf(" %d",u->v);
49     read(u->ch[1]);
50     delete u;
51 }
52 int cmp(const void*a,const void*b) { return *(int*)b-*(int*)a; }
53 int main()
54 {
55     //freopen("/home/user/桌面/in","r",stdin);
56     scanf("%d",&T);
57     int n;
58     while(T--)
59     {
60         scanf("%d",&n);
61         for(int i=1;i<=n;i++) scanf("%d%d",&a[i][0],&a[i][1]);
62         qsort(a+1,n,sizeof(a[0]),cmp);
63         int i;
64         node *root=NULL;
65         for(i=1;i<=n;i++)
66         {
67             if(a[i][1]>=i) break;
68             int pos=std::min(a[i][1],i-1-a[i][1]);
69             insert(root,pos,a[i][0]);
70         }
71         printf("Case #%d:",cas++);
72         if(i<=n) { puts(" impossible");continue; }
73         read(root);
74         printf("\n");
75     }
76     //printf("time=%.3lf",(double)clock()/CLOCKS_PER_SEC);
77     return 0;
78 }

时间: 2024-08-24 04:09:41

hdu 5493 Queue treap实现将元素快速插入到第i个位置的相关文章

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,

【线段树】HDU 5493 Queue (2015 ACM/ICPC Asia Regional Hefei Online)

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5493 题目大意: N个人,每个人有一个唯一的高度h,还有一个排名r,表示它前面或后面比它高的人的个数,求按身高字典序最小同时满足排名的身高排列. 题目思路: [线段树] 首先可以知道,一个人前面或后面有r个人比他高,那么他是第r+1高或第n-i-r+1高,i为这个人是第几高的. 所以先将人按照身高从小到大排序,接下来,把当前这个人放在第k=min(r+1,n-i-r+1)高的位置. 用线段树维护包

HDU 5493 Queue

Queue Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 68    Accepted Submission(s): 40 Problem DescriptionN people numbered from 1 to N are waiting in a bank for service. They all stand in a que

hdu 4965 Fast Matrix Calculation(矩阵快速幂)2014多校训练第9场

Fast Matrix Calculation                                                                   Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Problem Description One day, Alice and Bob felt bored again, Bob knows Ali

hdu 4441 Queue Sequence(splay)

题目链接:hdu 4441 Queue Sequence 这题看了题解写的,题解传送门 1 #include<bits/stdc++.h> 2 #define F(i,a,b) for(int i=a;i<=b;++i) 3 #define ls l,m,rt<<1 4 #define rs m+1,r,rt<<1|1 5 using namespace std; 6 typedef long long ll; 7 8 const int N=1e6+7; 9 i

HDU 5171 GTY&#39;s birthday gift 矩阵快速幂

点击打开链接 GTY's birthday gift Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 225    Accepted Submission(s): 78 Problem Description FFZ's birthday is coming. GTY wants to give a gift to ZZF. He as

HDU 4965 Fast Matrix Calculation(矩阵快速幂)

HDU 4965 Fast Matrix Calculation 题目链接 矩阵相乘为AxBxAxB...乘nn次,可以变成Ax(BxAxBxA...)xB,中间乘n n - 1次,这样中间的矩阵一个只有6x6,就可以用矩阵快速幂搞了 代码: #include <cstdio> #include <cstring> const int N = 1005; const int M = 10; int n, m; int A[N][M], B[M][N], C[M][M], CC[N]

hdu 4704 Sum (费马小定理+快速幂)

//(2^n-1)%mod //费马小定理:a^n ≡ a^(n%(m-1)) * a^(m-1)≡ a^(n%(m-1)) (mod m) # include <stdio.h> # include <algorithm> # include <string.h> # define mod 1000000007 using namespace std; __int64 pow(__int64 n) { __int64 p=1,q=2; while(n) { if(n%

HDU 2256 Problem of Precision (矩阵快速幂)

HDU 2256 Problem of Precision (矩阵快速幂) ACM 题目地址:HDU 2256 Problem of Precision 题意: 给出一个式子,求值. 分析: 推起来最后那步会比较难想. 具体过程见: 表示共轭只听说过复数的和图的... 这构题痕迹好明显... 跟基友开玩笑说:如果遇到这种题,推到Xn+Yn*sqrt(6)这步时,打表最多只能打到10就爆int了,这是输出正解和Xn,说不定眼神好能发现ans = Xn * 2 - 1呢.= =... 代码: /*