• 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;
    }
  • 相关阅读:
    ServU使用方法及应用技巧
    Mozilla公布火狐4详情:更快 更支持开放标准
    FastReport4.6程序员手册_翻译 转
    Delphi调用C写的dll
    动态创建Fastreport
    字符串通用类
    去除全角半角字符
    系统运行的命令集锦
    打印机的大小设置
    旋转字体的设置
  • 原文地址:https://www.cnblogs.com/shinecheng/p/3654184.html
Copyright © 2020-2023  润新知