poj 2828 Buy Tickets (線段樹)

小記: 這題之前想的簡單了, 後來看了樣例,發現了自己想法的錯誤


思路:一開始便發現這題,應該反過來思考的。但是用線段樹解決還是有點沒想到。

方法是:從後面開始看起,這樣計算完它之後,計算後面的值的時候不會影響之前計算過了的結果。相當於無後效性

對每個值 有一個 pos值,那麼其所在位置至少是pos+1之後,因爲pos值是從0開始的,正常的位置是從1開始的

所以,以pos值建線段樹, 目的是在pos+1位置處放下當前的value,而有可能pos+1位置已經被佔用了,所以要往後推

這裏我們給線段樹的每個節點加一個space,代表這一段還有多少個位置可以使用,因爲pos+1是從1開始數起的,

所以線段樹二分時,左邊的空間夠的話,就直接進入左邊,什麼都不用改,而若不夠,則要進入右邊,但是值要減去左邊的space值,

這樣求得最後的位置就必然是答案了,而當那個位置確定下來的時候,我們就應該記錄下來,開個數組記錄即可。


代碼:

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include <map>
#include <set>
#include <vector>
#include <stack>
#include <queue>
#include <algorithm>

using namespace std;

#define mst(a,b) memset(a,b,sizeof(a))
#define REP(a,b,c) for(int a = b; a < c; ++a)
#define eps 10e-8

const int MAX_ = 200010;
const int N = 100010;
const int INF = 0x7fffffff;

struct node{
    int l, r;
    int space;
}tree[MAX_*5];

int ans[MAX_];
int a[MAX_], b[MAX_];

void build(int l, int r, int k)
{
    if(l == r){
        tree[k].l = l;
        tree[k].r = r;
        tree[k].space = 1;
        return ;
    }

    int mid = l + (r-l)/2;
    tree[k].l = l;
    tree[k].r = r;

    build(l, mid, k<<1);
    build(mid+1, r, (k<<1)|1);

    tree[k].space = tree[k<<1].space + tree[(k<<1)|1].space;

}

void insert(int p, int value, int k)
{
    if(tree[k].l == tree[k].r){
        tree[k].space = 0;
        ans[tree[k].l] = value;
        return ;
    }

    if(p <= tree[k<<1].space){
        insert(p, value, k<<1);
    }
    else{
        insert(p-tree[k<<1].space, value, (k<<1)|1);
    }

    tree[k].space = tree[k<<1].space + tree[(k<<1)|1].space;
}


int main(){
	int n, m;
	while(~scanf("%d", &n)){
        REP(i, 0, n){
            scanf("%d%d", &a[i], &b[i]);
        }
        build(0, n-1, 1);

        for(int i = n-1; i > -1; --i){
            insert(a[i]+1, b[i], 1);
        }

        printf("%d", ans[0]);
        REP(i, 1, n){
            printf(" %d",ans[i]);
        }
        printf("\n");
	}
	return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章