티켓 POJ 주문 - 2828 + 세그먼트 트리의 생각을

티켓 POJ 주문 - 2828 + 세그먼트 트리의 생각을

문제의 의미

N 개별 티켓을 가지고 있다고하지만, 그것은, 큐가 마침내 무슨 일이 벌어지고 있는지 질문한다 큐 점프 n 개의 개별로 이동합니다. 큐 입력을 두 숫자를 이동, 첫 번째, 두 번째는 사람의 수, 잘 최종 출력 번호 얼마나 많은 사람들 앞에 있습니다.

문제 해결 아이디어

마지막 사람 후에 완료 큐를 이동할 수 있기 때문에이 문제가 뒤쪽에 대처하기 위해, 다른 사람에게 영향을 미치지 않습니다. 그의 앞에 n 개의 사람들은 그가 그렇게 라인에 그의 앞에 n 개의 사람들이, 우리가 그 위치를 알 필요가 와서, N + 1 개의 위치입니다있다. 각 위치에 대한 하나 개의 기본 없습니다.

코드의 자세한 모습.

코드 구현

#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
#define ls (rt<<1)
#define rs (rt<<1|1)
#define mid ( (t[rt].l+t[rt].r)>>1 )
using namespace std;
const int maxn=2e5+7;
struct node{
    int l, r;
    int sum, val;//sum记录这个区间内有多少空位置,val记录这个人的编号
}t[maxn<<2];
struct note{//记录这n个人的插队的顺序
    int pos, val;
}a[maxn];
int n; 
void up(int rt)
{
    t[rt].sum=t[ls].sum+t[rs].sum;
}
void build(int rt, int l, int r)
{
    t[rt].l=l;
    t[rt].r=r;
    t[rt].sum=r-l+1;
    if(l==r) return ;
    build(ls, l, mid);
    build(rs, mid+1, r);
}
void update(int rt, int pos, int val)
{
    if(t[rt].l==t[rt].r)
    {
        t[rt].sum--;
        t[rt].val=val;
        return ;
    }
    if(t[ls].sum>=pos)
        update(ls, pos, val);
    else 
        update(rs, pos-t[ls].sum, val);
    up(rt);
}
void query(int rt)
{
    if(t[rt].l==t[rt].r)
    {
        printf("%d ", t[rt].val);
        return ;
    }
    query(ls);
    query(rs);
}
int main() 
{
    while(scanf("%d", &n)!=EOF)
    {
        for(int i=1; i<=n; i++)
        {
            scanf("%d%d", &a[i].pos, &a[i].val);
        }
        build(1, 1, n);
        for(int i=n; i>=1; i--)
        {
            update(1, a[i].pos+1, a[i].val);
        }
        query(1);
        printf("\n");
    }
    return 0;
}

추천

출처www.cnblogs.com/alking1001/p/11423289.html