您的位置:首页 > 产品设计 > UI/UE

树状数组+二分||线段树 HDOJ 5493 Queue

2015-09-28 16:29 513 查看
题目传送门

题意:已知每个人的独一无二的身高以及排在他前面或者后面比他高的人数,问身高字典序最小的排法

分析:首先对身高从矮到高排序,那么可以知道每个人有多少人的身高比他高,那么取较小值(k[i], n - i - k[i]),若后者小于0则无解。然后可以理解为每个人前面要留出p + 1个位子给高个的人,可用线段树维护,s[rt] 表示当前线段还能空出的位子数。当然也能用树状数组+二分查找位子的方法。

/************************************************
* Author        :Running_Time
* Created Time  :2015/9/28 星期一 12:01:30
* File Name     :J.cpp
************************************************/

#include <cstdio>
#include <algorithm>
#include <iostream>
#include <sstream>
#include <cstring>
#include <cmath>
#include <string>
#include <vector>
#include <queue>
#include <deque>
#include <stack>
#include <list>
#include <map>
#include <set>
#include <bitset>
#include <cstdlib>
#include <ctime>
using namespace std;

#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
typedef long long ll;
const int N = 1e5 + 10;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
const double EPS = 1e-8;
struct ST   {
int s[N<<2], ans
;
void push_up(int rt)    {
s[rt] = s[rt<<1] + s[rt<<1|1];
}
void build(int l, int r, int rt)    {
if (l == r) {
s[rt] = 1;  return ;
}
int mid = (l + r) >> 1;
build (lson);   build (rson);
push_up (rt);
}
void updata(int p, int v, int l, int r, int rt) {
if (l == r) {
ans[l] = v; s[rt] = 0;
return ;
}
int mid = (l + r) >> 1;
if (p <= s[rt<<1]) {
updata (p, v, lson);
}
else    updata (p - s[rt<<1], v, rson);
push_up (rt);
}
}st;
struct PP   {
int h, k;
bool operator < (const PP &r) const    {
return h < r.h;
}
}p
;

int main(void)    {
int T, cas = 0; scanf ("%d", &T);
while (T--) {
int n;  scanf ("%d", &n);
for (int i=1; i<=n; ++i)    {
scanf ("%d%d", &p[i].h, &p[i].k);
}
sort (p+1, p+1+n);
st.build (1, n, 1);
bool flag = true;
for (int i=1; i<=n; ++i)    {
int pos = min (p[i].k, n - i - p[i].k);
if (pos < 0)    {
flag = false;   break;
}
st.updata (pos + 1, p[i].h, 1, n, 1);
}
printf ("Case #%d: ", ++cas);
if (!flag)  puts ("impossible");
else    {
for (int i=1; i<=n; ++i)    {
printf ("%d%c", st.ans[i], i == n ? '\n' : ' ');
}
}
}

return 0;
}


/************************************************
* Author        :Running_Time
* Created Time  :2015/9/28 星期一 15:48:08
* File Name     :J_BIT.cpp
************************************************/

#include <cstdio>
#include <algorithm>
#include <iostream>
#include <sstream>
#include <cstring>
#include <cmath>
#include <string>
#include <vector>
#include <queue>
#include <deque>
#include <stack>
#include <list>
#include <map>
#include <set>
#include <bitset>
#include <cstdlib>
#include <ctime>
using namespace std;

#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
typedef long long ll;
const int N = 1e5 + 10;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
const double EPS = 1e-8;
struct PP   {
int h, k;
bool operator < (const PP &r) const    {
return h < r.h;
}
}p
;
struct BIT  {
int c
, SZ;
void init(int n) {
memset (c, 0, sizeof (c));
SZ = n;
}
void updata(int i, int x)   {
while (i <= SZ)   {
c[i] += x;  i += i & (-i);
}
}
int query(int i)    {
int ret = 0;
while (i)   {
ret += c[i];    i -= i & (-i);
}
return ret;
}
int my_binary_search(int l, int r, int k)   {
while (l <= r)  {
int mid = (l + r) >> 1;
if (mid - query (mid) < k)   l = mid + 1;
else if (mid - query (mid) == k)    {
if (query (mid) - query (mid - 1) == 1) r = mid - 1;
else    return mid;
}
else    r = mid - 1;
}
return -1;
}
}bit;
int ans
;

int main(void)    {
int T, cas = 0; scanf ("%d", &T);
while (T--) {
int n;  scanf ("%d", &n);
for (int i=1; i<=n; ++i)    {
scanf ("%d%d", &p[i].h, &p[i].k);
}
sort (p+1, p+1+n);
bit.init (n);
bool flag = true;
for (int i=1; i<=n; ++i)    {
int pos = min (p[i].k, n - i - p[i].k);
if (pos < 0)    {
flag = false;   break;
}
int x = bit.my_binary_search (1, n, pos + 1);
ans[x] = p[i].h;
bit.updata (x, 1);
}
printf ("Case #%d: ", ++cas);
if (!flag)  puts ("impossible");
else    {
for (int i=1; i<=n; ++i)    {
printf ("%d%c", ans[i], i == n ? '\n' : ' ');
}
}
}

return 0;
}


  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: