HDU 5493 Queue (线段树) 2015合肥网络赛
2015-09-28 16:40
573 查看
题意:
给定N<105个人的序列,N个(height,k)二元组描述这个序列
height:=这个人的身高,k:=这个人的左边或者右边有k个人比他高
构造一个字典序最小的序列满足这些条件
分析:
从高到低放或者从低到高放都可以,由于本题要输出字典序最小的序列,所以我们使用从低到高放
由于从低到高放,之后放进去的是都是比当前高的
考虑当前当前放进去的第i个人,要满足后来的(即比他高的)有恰好k个在他前面或者在他后面
考虑有后来的k个人在他前面就是前面预留出k个位置
考虑有后来的k个人在他后面,已经放了i−1个人,剩下有n−(i−1)个人,再放k个在后面,还有n−(i−1)−k个,再去掉自己
那么问题就转化成了前面预留n−(i−1)−k−1=>n−i−k个
由于要字典序最小的,小的尽量往前放,所以取个min(k,n−i−k),如果这个值为负了,那么就表示不能放,就是impossible了
接下来就是普通的线段树求第min(k,n−i−k)+1个位置放进去当前这个人,维护区间坑位的个数,查询的时候同时维护一下ans数组就好了
代码:
给定N<105个人的序列,N个(height,k)二元组描述这个序列
height:=这个人的身高,k:=这个人的左边或者右边有k个人比他高
构造一个字典序最小的序列满足这些条件
分析:
从高到低放或者从低到高放都可以,由于本题要输出字典序最小的序列,所以我们使用从低到高放
由于从低到高放,之后放进去的是都是比当前高的
考虑当前当前放进去的第i个人,要满足后来的(即比他高的)有恰好k个在他前面或者在他后面
考虑有后来的k个人在他前面就是前面预留出k个位置
考虑有后来的k个人在他后面,已经放了i−1个人,剩下有n−(i−1)个人,再放k个在后面,还有n−(i−1)−k个,再去掉自己
那么问题就转化成了前面预留n−(i−1)−k−1=>n−i−k个
由于要字典序最小的,小的尽量往前放,所以取个min(k,n−i−k),如果这个值为负了,那么就表示不能放,就是impossible了
接下来就是普通的线段树求第min(k,n−i−k)+1个位置放进去当前这个人,维护区间坑位的个数,查询的时候同时维护一下ans数组就好了
代码:
// // Created by TaoSama on 2015-09-28 // Copyright (c) 2015 TaoSama. All rights reserved. // //#pragma comment(linker, "/STACK:1024000000,1024000000") #include <algorithm> #include <cctype> #include <cmath> #include <cstdio> #include <cstdlib> #include <cstring> #include <iomanip> #include <iostream> #include <map> #include <queue> #include <string> #include <set> #include <vector> using namespace std; #define pr(x) cout << #x << " = " << x << " " #define prln(x) cout << #x << " = " << x << endl const int N = 1e5 + 10, INF = 0x3f3f3f3f, MOD = 1e9 + 7; int n, ans ; int sum[N << 2]; typedef pair<int, int> P; P a ; #define root 1, n, 1 #define lson l, m, rt << 1 #define rson m + 1, r, rt << 1 | 1 void build(int l, int r, int rt) { sum[rt] = r - l + 1; if(l == r) return; int m = l + r >> 1; build(lson); build(rson); } void update(int k, int v, int l, int r, int rt) { --sum[rt]; if(l == r) { ans[l] = v; return; } int m = l + r >> 1; if(sum[rt << 1] > k) update(k, v, lson); else update(k - sum[rt << 1], v, rson); } int main() { #ifdef LOCAL freopen("in.txt", "r", stdin); // freopen("out.txt","w",stdout); #endif ios_base::sync_with_stdio(0); int t; scanf("%d", &t); int kase = 0; while(t--) { scanf("%d", &n); for(int i = 1; i <= n; ++i) scanf("%d%d", &a[i].first, &a[i].second); sort(a + 1, a + 1 + n); build(root); bool ok = true; for(int i = 1; i <= n; ++i) { int k = a[i].second, v = a[i].first; k = min(k, n - i - k); if(k < 0) { ok = false; break; } update(k, v, root); } printf("Case #%d: ", ++kase); if(!ok) puts("impossible"); else for(int i = 1; i <= n; ++i) printf("%d%c", ans[i], " \n"[i == n]); } return 0; }
相关文章推荐
- 线段树题集
- hdu1754
- HDU1394
- 敌兵布阵 (1)
- I Hate It (1)
- LCIS (2)
- A Simple Problem with Integers (2)
- Mayor's posters (3)
- Buy Tickets (3)
- 线段树
- UVA - 12532 Interval Product
- POJ 3264 Balanced Lineup
- hdu 1542 求矩形并的面积
- 关于数据结构之线段树
- poj 3225 关于集合运算
- poj 2352
- hdu1166敌兵布阵(线段树点修改)
- POJ 2352 Stars 线段树 pascal
- hdu 1698 Just A Hook 线段树的一道题
- HDU 1754 I Hate It