POJ_2828_Buy Tickets

题意:插队问题;

总结:线段树基础不牢,建树,更新尚不熟悉,注意加强理解记忆。

主要理解:(单点更新,逆序插入)

发生插队时,前面的队伍是连续没有空位的,即pos:2,1,这种情况不会出现,至少应该为pos:1,2,1

插入顺序是逆序的(最后插入的val的位置不会再发生变化),如果正序插入则每个val的顺序是动态的。

插入pos,那么在pos这个位置之前应该还有pos-1个空位。

访问右节点的时候注意pos要修改,改为pos-sum[rt],即整个线段的第pos个空位,在下一个右儿子那的第pos-sum[rt]个空位。

void Insert(int pos,int val,int l,int r,int rt)
{
    if(l==r)
    {
        spare[rt]=0;
        seq[l]=val;
        return;
    }
    int mid=(r+l)>>1;
    if(pos<=spare[rt<<1])
        Insert(pos,val,l,mid,rt<<1);
    else
        Insert(pos-spare[rt<<1],val,mid+1,r,rt<<1|1);
    PushUp(rt);
}

代码:

#include<iostream>
#include<cstdio>
using namespace std;

#define N 200005

int spare[N<<2];
int seq[N];

void PushUp(int rt)
{
    spare[rt]=spare[rt<<1]+spare[rt<<1|1];
}

void build(int l,int r,int rt)
{
    if(l==r)
    {
        spare[rt]=1;
        return;
    }
    int mid=(l+r)>>1;
    build(l,mid,rt<<1);
    build(mid+1,r,rt<<1|1);
    PushUp(rt);
}

void Insert(int pos,int val,int l,int r,int rt)
{
    if(l==r)
    {
        spare[rt]=0;
        seq[l]=val;
        return;
    }
    int mid=(r+l)>>1;
    if(pos<=spare[rt<<1])
        Insert(pos,val,l,mid,rt<<1);
    else
        Insert(pos-spare[rt<<1],val,mid+1,r,rt<<1|1);
    PushUp(rt);
}

int main()
{
    int n,p[N],v[N];
    while(scanf("%d",&n)!=EOF)
    {
        build(1,n,1);
        int i;
        for(i=1;i<=n;i++)
        {
            scanf("%d%d",&p[i],&v[i]);
            p[i]++;
        }
        for(i=n;i>0;i--)
        {
            Insert(p[i],v[i],1,n,1);
        }
        for(i=1;i<=n;i++)
        {
            if(i!=n)
                printf("%d ",seq[i]);
            else
                printf("%d\n",seq[i]);
        }
     /*for(i=1;i<=n;i++)         //如果这样输出就会超时,线段树容易超时
        {       printf("%d",seq[i]);
            if(i!=n)
                printf(" ");
            else
                printf("\n");
        }*/
} return 0; }

  

时间: 2024-11-09 00:09:57

POJ_2828_Buy Tickets的相关文章

【SGU 390】Tickets (数位DP)

Tickets Description Conductor is quite a boring profession, as all you have to do is just to sell tickets to the passengers. So no wonder that once upon a time in a faraway galaxy one conductor decided to diversify this occupation. Now this conductor

[2016-03-27][HDU][1260][Tickets]

时间:2016-03-27 22:37:37 星期日 题目编号:[2016-03-27][HDU][1260][Tickets] 遇到的问题:分钟数字,除以60以后还要模60 t / 60 % 60 #include <cstdio> #include <algorithm> using namespace std; typedef long long LL; const int maxk = 2000 + 10; int s[maxk],d[maxk]; int dp[maxk]

ural 1217. Unlucky Tickets

1217. Unlucky Tickets Time limit: 1.0 secondMemory limit: 64 MB Strange people live in Moscow! Each time in the bus, getting a ticket with a 6-digit number, they try to sum up the first half of digits and the last half of digits. If these two sums ar

POJ 2828 Buy Tickets(线段树--单点更新)

Buy Tickets Time Limit: 4000MS   Memory Limit: 65536K Total Submissions: 16196   Accepted: 8059 Description Railway tickets were difficult to buy around the Lunar New Year in China, so we must get up early and join a long queue- The Lunar New Year wa

poj 2828 Buy Tickets 【线段树点更新】

题目:poj 2828 Buy Tickets 题意:有n个人排队,每个人有一个价值和要插的位置,然后当要插的位置上有人时所有的人向后移动一位当这个插入到这儿,如果没有直接插进去. 分析:分析发现直接插入移动的话花时间太多,我们可不可以用逆向思维.从后往前来,因为最后一个位置是肯定能确定的,而其他的则插入空的第某个位置. 比如第一组样例: 4 0 77 1 51 1 33 2 69 开始时候位置都为空 编号0 1 2 3 首先从最后一个来2 69 第二个位置空,则可以直接放 然后编号变为0 1

POJ 2828 Buy Tickets(线段树)

Language: Default Buy Tickets Time Limit: 4000MS   Memory Limit: 65536K Total Submissions: 13847   Accepted: 6926 Description Railway tickets were difficult to buy around the Lunar New Year in China, so we must get up early and join a long queue- The

Poj2828Buy Tickets线段树

倒着搞就可以了,先进会被后面覆盖. #include <cstdio> #include <cstring> #include <algorithm> #include <climits> #include <string> #include <iostream> #include <map> #include <cstdlib> #include <list> #include <set&g

poj 2828 Buy Tickets

Buy Tickets Time Limit: 4000MS   Memory Limit: 65536K Total Submissions: 13277   Accepted: 6595 Description Railway tickets were difficult to buy around the Lunar New Year in China, so we must get up early and join a long queue- The Lunar New Year wa

POJ训练计划2828_Buy Tickets(线段树/单点更新)

解题报告 题意: 插队完的顺序. 思路: 倒着处理数据,第i个人占据第j=pos[i]+1个的空位. 线段树维护区间空位信息. #include <iostream> #include <cstdio> #include <cstring> using namespace std; struct node { int x,v; } num[201000]; int sum[1000000],ans[201000]; void cbtree(int rt,int l,in