• POJ-2828 Buy Tickets---线段树+逆序


    题目链接:

    https://cn.vjudge.net/problem/POJ-2828

    题目大意:

    插队的问题,每个案例给出n,代表有n个插队的,每个给出p,v,意思是代号为v的人插在了第p个人的后面,问最后的队伍的排列?

    解题思路:

    如果从前往后递推,每次插入在前面的话,后面的人都需要往后移动,所以考虑从后往前放

    从后往前退的话每次可以推到确定的位置,插入在位置为i的地方,说明按从前往后放的时候前面有i个人,从后往前放的话就是前面有i个空格,放在第i+1个空格的地方,这样逆序放的话每次都可以放在确定的位置,不用移动。

    线段树存的是区间内空格的数目,每次放的时候,位置需要加1,因为位置i说明放在前面有i个空格,该点在第i+1个空格处。

     1 #include<iostream>
     2 #include<cstdio>
     3 #define MID(l, r) (l + (r - l) / 2)
     4 #define lson(o) (o * 2)
     5 #define rson(o) (o * 2 + 1)
     6 using namespace std;
     7 typedef long long ll;
     8 const int INF = 1e9 +7;
     9 const int maxn = 1e6 + 10;
    10 int  h, w, n;
    11 struct node
    12 {
    13     int l, r, sum;
    14 }tree[maxn];
    15 int ans[maxn];
    16 void build(int o, int l, int r)
    17 {
    18     tree[o].l = l, tree[o].r = r;
    19     if(l == r)
    20     {
    21         tree[o].sum = 1;
    22         return;
    23     }
    24     int m = MID(l, r);
    25     int lc = lson(o), rc = rson(o);
    26     build(lc, l, m);
    27     build(rc, m + 1, r);
    28     tree[o].sum = tree[lc].sum + tree[rc].sum;
    29 }
    30 void insert(int o, int a, int b)//a个空位
    31 {
    32     if(tree[o].l == tree[o].r)
    33     {
    34         ans[tree[o].l] = b;
    35         tree[o].sum = 0;
    36         return;
    37     }
    38     int lc = lson(o), rc = rson(o);
    39     if(a <= tree[lc].sum)insert(lc, a, b);//空位数目小于等于左子树,在左子树中插入
    40     else insert(rc, a - tree[lc].sum, b);//空位数目大于左子树,在右子树插入,此时a需要减去左子树的空位数目
    41     tree[o].sum = tree[lc].sum + tree[rc].sum;//在插如之后空位数目发生变化,需要维护本节点的sum值
    42 }
    43 int a[maxn], b[maxn];
    44 int main()
    45 {
    46     int n, m;
    47     while(scanf("%d", &n) != EOF)
    48     {
    49         build(1, 1, n);
    50         for(int i = 0; i < n; i++)scanf("%d%d", &a[i], &b[i]), a[i]++;//空位数目自加一,表示自己在第a[i]个空位处
    51         for(int i = n - 1; i >= 0; i--)
    52         {
    53             insert(1, a[i], b[i]);
    54         }
    55         for(int i = 1; i < n; i++)printf("%d ", ans[i]);
    56         printf("%d
    ", ans[n]);
    57 
    58     }
    59     return 0;
    60 }
  • 相关阅读:
    js sort方法根据数组中对象的某一个属性值进行排序
    ES6之Array.from()方法
    windows安装gnvm安装教程,node多版本解决方案
    Singleton模式的两种实现形式
    java 一组数随机组合求和等于目标数
    与公式相关的代码片段
    项目总结【Excel中附件导出和导入】
    Hook钩子C#实例
    网上以讹传讹的逻辑推理题:电影票问题
    原创:仿AspNetPager写的JS分页控件,适合ajax调用
  • 原文地址:https://www.cnblogs.com/fzl194/p/9026853.html
Copyright © 2020-2023  润新知