zoukankan      html  css  js  c++  java
  • POJ_2828_Buy Tickets

    题意:插队问题;

     2016.5.20,复习这道题。

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

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

    发生插队时,前面的队伍是连续没有空位的,即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
    ",seq[i]);
            }
         /*for(i=1;i<=n;i++)         //如果这样输出就会超时,线段树容易超时
            {
           printf("%d",seq[i]); if(i!=n) printf(" "); else printf(" "); }*/
    } return 0; }

      

  • 相关阅读:
    Linux各主要发行版的包管理命令对照
    JDK 生成数字证书
    AbatorForEclipse插件使用总结
    [转载]在rhel 6 x86_64 上安装oracle 11g xe
    【转载】PL/SQL配置连接ORACLE
    Archlive新年第一棒: 基于2.6.37稳定内核的archlive20110107
    基于Arch的live系统
    【转】MyEclipse 9.0正式版官网下载(附Win+Llinux激活方法、汉化包)
    Exception in thread main java.lang.NoClassDefFoundError: org/apache/juli/logging/LogFacto
    MyEclipse 8.6插件下载
  • 原文地址:https://www.cnblogs.com/jasonlixuetao/p/4732056.html
Copyright © 2011-2022 走看看