H - Buy Tickets
这个题目还是比较简单的,其实有思路,不过中途又断了,最后写了一发别的想法的T了。
然后脑子就有点糊涂,不应该啊,这个题目应该会写才对,这个和之前的一个题目很像
G - Queue HDU - 5493 线段树+二分
这个题目也是找位置,但是这个题目怎么找呢?
这个要从后往前面找,每次把最后的位置放进去,然后剩下的队列当成一个新的空的序列,再继续插入数字。
但是这个题目不能用线段树,因为线段树比较慢,用树状数组恰好,线段树会T。
#include <cstdio> #include <cstdlib> #include <cstring> #include <queue> #include <vector> #include <string> #include <algorithm> #include <iostream> #include <map> #include <list> #define inf 0x3f3f3f3f #define inf64 0x3f3f3f3f3f3f3f3f using namespace std; typedef long long ll; const int maxn = 2e5 + 10; int a[maxn], b[maxn]; int sum[maxn], n; int ans[maxn]; int lowbit(int x) { return x & (-x); } void update(int i, int k) { while (i < n) { sum[i] += k; i += lowbit(i); } } int getsum(int x) { int res = 0; while (x > 0) { res += sum[x]; x -= lowbit(x); } return res; } int main() { while(scanf("%d",&n)!=EOF) { for (int i = 1; i <= n; i++) scanf("%d%d", &a[i], &b[i]), sum[i] = 0; for(int i=n;i>=1;i--) { int l = a[i]+1, r = n; while(l<=r) { int mid = (l + r) >> 1; int res = mid - getsum(mid); if (res > a[i]) r = mid - 1; else l = mid + 1; } ans[r + 1] = b[i]; update(r + 1, 1); } for (int i = 1; i < n; i++) printf("%d ", ans[i]); printf("%d ", ans[n]); } return 0; }