zoukankan      html  css  js  c++  java
  • HDU 5592

    原题:

    http://acm.hdu.edu.cn/showproblem.php?pid=5592

    线段树的变形,先说思路。

    题目中给出了当前节点之前的逆序对数,则p[i]-p[i-1]就是对于p[i]来说,新增的逆序数,也就是比p[i]大的数,所以这时要考虑倒着处理,用线段树维护哪些数已经使用,哪些还未使用,p[i]-p[i-1]+1就是在还能用的序列中,第几大的数。我们用1表示数还没用,用0表示已经用了,这里就用到线段树的变形,每个节点维护着当前区间有几个1,我们的原则是先访问线段树的右节点,再左节点,因为右边的数大嘛。

    需要注意的是,刚开始要将所有的叶子节点更新为1,再就是,当右节点不满足条件,要进入左节点时,一定用val减去右节点的值。

     1 #include<stdio.h>
     2 #include<string.h>
     3 #define maxn 50005
     4 int a[maxn],b[maxn],tree[maxn<<2];
     5 int n,k;
     6 void init(){
     7     k = 1;
     8     while(k<n)
     9         k <<= 1;
    10     memset(tree,0,sizeof(tree));
    11 } 
    12 void upgrade(int index,int val){
    13     index = index + k - 1;
    14     tree[index] += val;
    15     index /= 2;
    16     while(index){
    17         tree[index] = tree[index*2] + tree[index*2+1];
    18         index /= 2;
    19     }
    20 }
    21 int query(int index,int l,int r,int val){
    22     if(l==r)
    23         return l;
    24     int m = (l+r)/2;
    25     if(tree[index*2+1]>val)
    26         query(index*2+1,m+1,r,val);
    27     else
    28         query(index*2,l,m,val-tree[index*2+1]);
    29 }
    30 int main(){
    31     int t;
    32     scanf("%d",&t);
    33     while(t--){
    34         scanf("%d",&n);
    35         init();
    36         for(int i = 1;i<=n;i++){
    37             scanf("%d",&a[i]);
    38             upgrade(i,1);
    39         }
    40         for(int i = n;i>0;i--){
    41             int val = a[i] - a[i-1];
    42             b[i] = query(1,1,k,val);
    43             upgrade(b[i],-1);
    44         }
    45         for(int i = 1;i<n;i++)
    46             printf("%d ",b[i]);
    47         printf("%d
    ",b[n]);
    48     }
    49     return 0;
    50 }
  • 相关阅读:
    ural(Timus) 1019 Line Painting
    ACMICPC Live Archive 2031 Dance Dance Revolution
    poj 3321 Apple Tree
    其他OJ 树型DP 选课
    poj 3548 Restoring the digits
    ACMICPC Live Archive 3031 Cable TV Network
    递归循环获取指定节点下面的所有子节点
    手动触发asp.net页面验证控件事件
    子级Repeater获取父级Repeater绑定项的值
    没有列名的数据绑定
  • 原文地址:https://www.cnblogs.com/zqy123/p/5051047.html
Copyright © 2011-2022 走看看