• poj 2828 Buy Tickets


    题目给出插队的过程,求最后队的序列。我当初想开一个大数组模拟,用1表示有人,0表示没人,从后往前推,每确定一个人,就把他所在位置的1改为0,剩下的人再根据0,1算序号。这个想法我放弃了,因为复杂度是O(n)的。后来我才恍然大悟,线段树不就是把对区间的操作从O(n)化为O(logn)的么?这样问题就解决了。

     1 #include <stdio.h>
     2 #include <string.h>
     3 const int N = 200010;
     4 int p[N],w[N],order[N];
     5 int tree[N<<2],D;
     6 void update(int n)
     7 {
     8     while(n)
     9     {
    10         tree[n>>1] = tree[n] + tree[n^1];
    11         n >>= 1;
    12     }
    13 }
    14 void push(int i)
    15 {
    16     int m,n = p[i]+1;
    17     for(m = 1; m < D;)
    18     {
    19         if(tree[m<<1] >= n) m <<= 1;
    20         else n -= tree[m<<1], m = m<<1|1;
    21     }
    22     tree[m] = 0;
    23     update(m);
    24     order[m-D] = w[i];
    25 }
    26 int main()
    27 {
    28     int n,i;
    29     while(~scanf("%d",&n))
    30     {
    31         for(D = 1; D < n; D <<= 1);
    32         memset(tree,0,sizeof tree);
    33         for(i = 0; i < n; i++)
    34             scanf("%d%d",&p[i],&w[i]), tree[D+i] = 1;
    35         for(i = D-1; i; i--)
    36             tree[i] = tree[i<<1] + tree[i<<1|1];
    37         for(i = n-1; i >= 0; i--)
    38             push(i);
    39         printf("%d",order[0]);
    40         for(i = 1; i < n; i++)
    41             printf(" %d",order[i]);
    42         printf("\n");
    43     }
    44     return 0;
    45 }
  • 相关阅读:
    python day05
    python day04
    python day03
    python day02
    计算机基本了解
    流程控制
    MFC程序中创建文件夹(文件路径)
    svn移动目录并且保存历史日志
    C++单例模式的问题
    PtInRect 的详细范围
  • 原文地址:https://www.cnblogs.com/lzxskjo/p/2661116.html
Copyright © 2020-2023  润新知