zoukankan      html  css  js  c++  java
  • poj2182

    题目意思:一个1-n的排列,给出每个数前面比他小的数的个数,求该序列

    思路:很明显从低往前确定数,比如序列为 1 2  1 0

    那么 最后一个一定是 1,因为前面没比他小的,

    倒数第二个为3,因为除去1,他是第二大的。。。。以此类推

    那么就变成模拟了。。所以我们可以用平衡树,或者线段树做,但是代码有点长。。

    所以自然想到用树状数组了。。

    具体如下:刚开始给每个位置赋值为1,找到这个数,那么就删掉。当前第k大实际上就是前面和为k的那个数。。。。输出并删除

                    这样就要用到二分找第k大的。。

      但一个问题是删完后会出现不只一个和为k的数,,解决办法只要取第一个就行了(想想就知道了)

     1 /*
     2   Source:poj2182
     3   Time:2013.5.1
     4   State:Accepted
     5 */
     6 #include <iostream>
     7 #include <cstring>
     8 #include <cstdio>
     9 #include <cmath>
    10 #include <algorithm>
    11 #define MXN 10000
    12 using namespace std;
    13 int n, a[MXN], sum[MXN], ans[MXN];
    14 bool  bo[MXN];
    15 
    16 int lowbit(int t){ return t & (-t); } //计算t末尾的0的个数,也可以用 t&(t ^ (t -1)) 的表达式求
    17 
    18 void updata(int k, int data){  //插入点(往其父节点更新)
    19     for (int i = k; i <= n; i += lowbit(i))
    20       sum[i] += data;
    21 }
    22 
    23 int getsum(int k){ //求和(往前,其并列节点)
    24     int ret = 0;
    25     for (int i = k; i > 0; i -= lowbit(i))
    26         ret += sum[i];
    27     return ret;
    28 }
    29 
    30 void init(){
    31     scanf("%d", &n);
    32     for (int i = 1; i <= n; ++i)
    33        updata(i, 1);
    34     for (int i = 1; i < n; ++i)
    35        scanf("%d", &a[i]);
    36 }
    37 
    38 int search(int x){
    39     int l = 1, r = n, mid, nowsum;
    40     while (l < r){
    41        mid = l + r >> 1,
    42        nowsum = getsum(mid);
    43        if (nowsum < x) l = mid + 1;
    44        else r = mid;
    45     }
    46     return l;
    47 }
    48 
    49 void solve(){
    50     int k;
    51     a[0] = 0;
    52     for (int i = n - 1; i >= 0; --i){
    53        k = search(a[i] + 1);
    54        ans[i] = k;
    55        updata(k, -1);
    56     }
    57     for (int i = 0; i < n; ++i)
    58         printf("%d\n", ans[i]);
    59 
    60 }
    61 
    62 int main(){
    63     freopen("poj2182.in","r", stdin);
    64     freopen("poj2812.out","w", stdout);
    65     init();
    66     solve();
    67 }
  • 相关阅读:
    AC自动机模板
    hdu 6034 贪心模拟 好坑
    UVA 10870
    hdu 2604 递推 矩阵快速幂
    hdu 3117 Fibonacci Numbers 矩阵快速幂+公式
    hdu 1575 Tr A 矩阵快速幂
    POJ_1151 扫描线+离散化+线段树
    HDU_2227 求不减子序列的个数(树状数组+DP)
    深夜敲模板_5——KMP
    深夜敲模板_4——无向图的割顶和桥
  • 原文地址:https://www.cnblogs.com/yzcstc/p/3053919.html
Copyright © 2011-2022 走看看