zoukankan      html  css  js  c++  java
  • poj 2828 buy Tickets 用线段树模拟带插入的队列 单点更新

    题目链接:

    http://poj.org/problem?id=2828

    题意:

    给出n个人,每人有一个应该在队列的位置和值,如果后面的人的位置和前面重复了,就插在前面。输出最后的队列

    题解:

    从后往前找位置,因为后面的人的位置总是不变的
    线段树,单点更新, 维护的v表示 这段区间一共有多少个空位置
    更新到叶子节点的时候:v=0,return L; 因为这个位置已经固定了,相当于在后面的人预留一个位置,相当于在考虑这个人不存在一样,再往前更新的时候就不会有问题。

    代码:

     1 #include <cstdio>
     2 #include <iostream>
     3 using namespace std;
     4 typedef long long ll;
     5 #define MS(a) memset(a,0,sizeof(a))
     6 #define MP make_pair
     7 #define PB push_back
     8 const int INF = 0x3f3f3f3f;
     9 const ll INFLL = 0x3f3f3f3f3f3f3f3fLL;
    10 inline ll read(){
    11     ll x=0,f=1;char ch=getchar();
    12     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    13     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    14     return x*f;
    15 }
    16 //////////////////////////////////////////////////////////////////////////
    17 const int maxn = 2e5+10;
    18 
    19 int b[maxn],c[maxn],ans[maxn];
    20 
    21 struct node{
    22     int l,r,v;
    23 }tree[maxn<<2];
    24 
    25 void pushup(int rt){
    26     tree[rt].v = tree[rt<<1].v + tree[rt<<1|1].v;
    27 }
    28 
    29 void build(int rt,int l,int r){
    30     tree[rt].l = l, tree[rt].r = r;
    31     tree[rt].v = r-l+1;
    32     if(l == r)
    33         return ;
    34 
    35     int mid = (l+r)/2;
    36     build(rt<<1,l,mid);
    37     build(rt<<1|1,mid+1,r);
    38     pushup(rt);
    39 }
    40 
    41 int update(int rt,int val){
    42     int L = tree[rt].l, R = tree[rt].r;
    43     if(L == R){
    44         tree[rt].v = 0;
    45         return L;
    46     }
    47     int pos = 0;
    48     if(tree[rt<<1].v >= val)
    49         pos = update(rt<<1,val);
    50     else
    51         pos = update(rt<<1|1,val-tree[rt<<1].v);
    52     pushup(rt);
    53     return pos;
    54 }
    55 
    56 int main(){
    57     int n;
    58     while(scanf("%d",&n)!=EOF){
    59         build(1,1,n);
    60         for(int i=1; i<=n; i++)
    61             b[i] = read(), c[i] = read();
    62         for(int i=n; i>=1; i--){
    63             int pos = update(1,b[i]+1);
    64             ans[pos] = c[i];
    65         }
    66         for(int i=1; i<=n; i++)
    67             cout << ans[i] << " ";
    68         cout << endl;
    69     }
    70 
    71     return 0;
    72 }
  • 相关阅读:
    【LeetCode】206. Reverse Linked List
    【LeetCode】160. Intersection of Two Linked Lists
    【LeetCode】190. Reverse Bits
    【LeetCode】165. Compare Version Numbers
    继续深入《一张神奇的图》
    Base64编码简介
    证明任意两个正整数相等(伪命题)
    DEADBEEF
    汉诺塔问题
    字符编码(2)-- 程序中的编码
  • 原文地址:https://www.cnblogs.com/yxg123123/p/6827652.html
Copyright © 2011-2022 走看看