• poj2182


    题意:1~n,乱序排列,告诉每个位置的前面的数字中比它小的数的个数,求每个位置的数字是多少

    分析:用树状数组来做,第i位如果是1,表示i在数列中的位置已经确定。全部读入到f[]后,从最后向前依次求出是几,因为每次对于未确定的最后一个数来说是可以根据它前面有多少数字比它小以及之前确定的数字(在它后面的数字)而确定它是几的。二分查找当前位置填几,设这个数字为a,应满足树状数组求和结果sum(a),即后面已经填好的比a小的个数,加上f[i],即前面比a小的个数,等于a-1。猜大了则结果大于a-1,猜小了则小于。找到后把树状数组第a位标1。时间复杂度为O((logn)^2 * n)

    View Code
    #include <iostream>
    #include
    <cstdlib>
    #include
    <cstring>
    #include
    <cstdio>
    usingnamespace std;

    #define maxn 8005

    int n, f[maxn];
    int ar[maxn];
    int ans[maxn];

    int lowb(int t)
    {
    return t &(-t);
    }

    void add(int i, int v)
    {
    for (; i < maxn; ar[i] += v, i += lowb(i));
    }

    int sum(int i)
    {
    int s =0;
    for (; i >0; s += ar[i], i -= lowb(i));
    return s;
    }

    int calspace(int index)
    {
    return index - sum(index);
    }

    int binarysearch(int a)
    {
    int l =1;
    int r = n;
    int mid;
    while (l < r)
    {
    mid
    = (l + r) /2;
    int temp = calspace(mid);
    if (temp < a)
    l
    = mid +1;
    else
    r
    = mid;
    }
    return l;
    }

    int main()
    {
    //freopen("t.txt", "r", stdin);
    scanf("%d", &n);
    f[
    0] =0;
    for (int i =1; i < n; i++)
    scanf(
    "%d", &f[i]);
    for (int i = n -1; i >=0; i--)
    {
    int a = binarysearch(f[i] +1);
    ans[i]
    = a;
    add(a,
    1);
    }
    for (int i =0; i < n; i++)
    printf(
    "%d\n", ans[i]);
    return0;
    }
  • 相关阅读:
    mysql单机多实例配置
    mysql中FILE权限
    手把手教你用 Git(转)
    单例模式
    Java中的枚举Enum
    常见排序算法的亲手实现(代码与注释)
    Java中的位运算
    重载
    Java中的boxing和unboxing(转)
    Java的transient关键字(转)
  • 原文地址:https://www.cnblogs.com/rainydays/p/2072849.html
Copyright © 2020-2023  润新知