H

H - Buy Tickets

 POJ - 2828 

这个题目还是比较简单的,其实有思路,不过中途又断了,最后写了一发别的想法的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;
}
View Code
原文地址:https://www.cnblogs.com/EchoZQN/p/11390575.html