zoukankan      html  css  js  c++  java
  • POJ 2828: Buy Tickets(线段树)

    扯淡:

    这题要赞。

    因为卡了我两次……

    第三次终于做出来了。。。好吧是看了别人代码之后T T。太弱太弱。。。

    题意:

    有n个人排队,但他们会插队。他们按先后顺序来到,每次每个人选择插在Pos[i]这个位置,问最后的排队情况(每个人用其val值表示)。(1 ≤ N ≤ 200,000)

    思路:

    容易想到,最后一个人,插哪,那它就在哪。

    也就是说,一个人的最后位置,只会被它后面的人影响到。

    再分析,就会发现,如果一个人插在Pos[i]这个位置,那么表示,它插入的时候,前面有Pos[i]个人(废话)。那么我们倒着计算的时候,由于他后面的人已经进来了,那么第i个人站的实际位置,是在它前面还有pos[i]个空位的位置(加上它本身这个空位一共是pos[i]+1个)

    这里,粗暴的是想用二分+线段树查找的算法,这样是logNlogN,实际上可以直接在线段树上完成。这点很赞!!!!!

    代码:

    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #define N 200010
    int tree[N<<2];
    int pos[N], a[N], val[N];
    
    void build() {
        memset(tree,0,sizeof(tree));
    }
    
    //int query(int L, int R, int l, int r, int rt) {
    //    if (L <= l && r <= R) {
    //        return tree[rt];
    //    }
    //    int mid = (l+r)/2;
    //    int ans = 0;
    //    if (L <= mid) ans += query(L, R, l, mid, rt<<1);
    //    if (R > mid) ans += query(L, R, mid+1, r, rt<<1|1);
    //    return ans;
    //}
    
    void insert(int x, int v, int l, int r, int rt) {
        //printf("[%d,%d] rt = %d
    ", l, r, rt);
        if (l == r) {
            tree[rt]++;
            a[l] = v;
            return ;
        }
        int mid = (l+r)/2;
        if (x <= (mid-l+1-tree[rt<<1])) insert(x,v,l,mid,rt<<1);
        else insert(x-(mid-l+1-tree[rt<<1]),v,mid+1,r,rt<<1|1);
    
        tree[rt] = tree[rt<<1] + tree[rt<<1|1];
    }
    
    int main() {
        int n;
        while (scanf("%d", &n) != EOF) {
            for (int i = 0; i < n; i++) {
                scanf("%d%d", &pos[i], &val[i]);
            }
            build();
    
            for (int i = n-1; i >= 0; i--) {
                insert(pos[i]+1,val[i],0,n,1);
            }
            
            for (int i = 0; i < n; i++) {
                printf(i==0?"%d":" %d", a[i]);
            }puts("");
        }
        return 0;
    }
  • 相关阅读:
    垃圾收集器与内存分配策略(二)之垃圾收集算法
    组合与继承
    垃圾收集器与内存分配策略(一)之对象存活判断
    虚拟机中对象的创建、内存布局、访问
    Java运行时数据区域划分
    Java操作excel表格
    位段
    sh -s用法
    ubutu14.04选中文本就会删除问题解决
    java容器-List
  • 原文地址:https://www.cnblogs.com/shinecheng/p/3654184.html
Copyright © 2011-2022 走看看