首页 > 其他分享 >P3103 [USACO14FEB] Airplane Boarding G

P3103 [USACO14FEB] Airplane Boarding G

时间:2025-01-07 19:00:51浏览次数:1  
标签:Boarding 整点 int pos tim USACO14FEB Airplane 奶牛 座位

P3103 [USACO14FEB] Airplane Boarding G

想象一下飞机有N个座位,N个座位相当于数轴上的1至N共N个整点,第1个座位在整点1处,第2个座位在整点2处,……第N个座位在整点N处。

有N个奶牛排好队,要登陆坐飞机,第N头奶牛在数轴的整点0处,第N−1头奶牛在数轴的整点−1处,……第1头奶牛在数轴的整点−N+1处。第i头奶牛的座位号是Si。注意:每头奶牛都有唯一的一个座位,不会出现多头奶牛有相同的座位号。

在每一秒钟,奶牛会向右移动一步到达下一个整点,前提是没有奶牛挡住它。 当第i头奶牛到达它的座位Si时,它需要花费Ti秒去把行李放到头顶的行李架上,然后坐到自己的位置上,在此过程中,由于飞机通道很窄,所以在第i头奶牛坐到自己座位之前,在它左边的所有奶牛都不能动,要等奶牛i放好行李坐好后才能动。

现在的问题是,至少要多少秒之后,所有的奶牛都能做到自己的座位上?

\(N \le2*10^5\)

Solution:

妙妙平衡树思维题,感觉可以入选我写过的的十佳题目了。

我们将点 \(i\) 的起点定义为 \(pos_i\)

首先我们很难不想到我们应该按照时间的顺序,也就是输入顺序的倒序来写这题,然后我们仔细思考一下就会发现其实答案由两部分组成:

从起点到终点的距离加上放行李的时间\(s_{i}-pos_{i}+t_{i}\) 和被挡路的时间 \(tim\).

前一半的答案是固定的,所以我们要做的是如何快速的统计一个点总共会被挡多久的路。

那么什么样的点 \(j\) 会挡当前点 \(i\) 的路呢?

首先要满足的肯定是 $pos_i<pos_j $ \(s_i<s_j\)

然后就是 \(\forall k\in[i+1,j] tim_j>tim_k\)

也就是说,如果一个点 \(j\) 出发的比当前点 \(i\) 早且,而且它被挡路的时间 \(tim_j>tim_{max}\) 它才有可能挡住点 \(j\) 及其后序节点(按时间顺序)的路。所以我们要将那些不满足 \(tim_j>tim_i\) 的点全部删除。这样我们就能保证在数据结构内的点全部都是满足有可能挡住 \(i\) 的。然后每个点的到达时间显然就是该数据结构内的最大值\(tim_{max}\) 加上前半部分的时间 \(s_i+pos_i+t_i\).

然后我们发现我们要维护一种数据结构,单点插入,区间删除,查询区间最大值.那就是平衡树了

然后这题就做完了

Code:

#include<bits/stdc++.h>
const int N=2e5+5;
using namespace std;
int rd(){return rand()*17+rand()*rand()+1;}
inline int Max(int x,int y){return x>y ? x : y;}
struct FHQ_Treap{
    int cnt=0;
    struct Tree{
        int ls,rs,x,y,ans,tag,pri;
    }t[N<<2];
    int Node(int x,int y)
    {
        t[++cnt]={0,0,x,y,y,0,rd()};
        return cnt;
    }
    void push(int x,int k){t[x].x-=k;t[x].y+=k,t[x].ans+=k,t[x].tag+=k;}
    void pushdown(int x)
    {
        if(!t[x].tag)return;
        if(t[x].ls)push(t[x].ls,t[x].tag);
        if(t[x].rs)push(t[x].rs,t[x].tag);
        t[x].tag=0;
    }
    void pushup(int x)
    {
        if(!x)return;
        t[x].ans=t[x].y;
        if(t[x].ls)t[x].ans=Max(t[x].ans,t[t[x].ls].ans);
        if(t[x].rs)t[x].ans=Max(t[x].ans,t[t[x].rs].ans);
        return ;
    }
    void splite_pos(int x,int &a,int &b,int k)
    {
        if(!x){a=b=0;return;}
        pushdown(x);
        if(k>=t[x].x) {a=x;splite_pos(t[x].rs,t[x].rs,b,k);}
        if(k<t[x].x){b=x;splite_pos(t[x].ls,a,t[x].ls,k);}
        pushup(x);
    }
    void splite_val(int x,int &a,int &b,int k)
    {
        if(!x){a=b=0;return;}
        pushdown(x);
        if(k>=t[x].y) {a=x;splite_val(t[x].rs,t[x].rs,b,k);}
        if(k<t[x].y){b=x;splite_val(t[x].ls,a,t[x].ls,k);}
        pushup(x);
    }
    int merge(int x,int y)
    {
        if(!x||!y)return x|y;
        pushdown(x);pushdown(y);
        if(t[x].pri<t[y].pri)
        {
            t[x].rs=merge(t[x].rs,y);
            pushup(x);return x;
        }
        else
        {
            t[y].ls=merge(x,t[y].ls);
            pushup(y);return y;
        }
    }
}T;
int s[N],t[N];
int n,rt,ans=0;
void work()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    cin>>n;
    rt=T.Node(0,0);
    for(int i=1;i<=n;i++)
    {
        cin>>s[i]>>t[i];
    }
    int a,b,c,tmp;
    for(int i=n;i;i--)
    {
        T.splite_pos(rt,a,b,s[i]);
        tmp=T.t[a].ans+s[i]+t[i];
        ans=Max(ans,tmp);
        T.push(a,1);
        T.splite_val(b,b,c,tmp-s[i]+1);
        rt=T.merge(a,T.merge(T.Node(s[i],tmp-s[i]+1),c));
    }
    cout<<ans;
}
int main()
{
    //freopen("P3103.in","r",stdin);freopen("P3103.out","w",stdout);
    work();
    return 0;
}

标签:Boarding,整点,int,pos,tim,USACO14FEB,Airplane,奶牛,座位
From: https://www.cnblogs.com/LG017/p/18658174

相关文章

  • windmill Airplane&Superblocks&Retool&Prefect&Airflow 可选工具
    现在调度工具是越来越多了,而且集成的能力也越来越强大了windmill是一个很不错的workflow调度平台功能很强大特性可扩展的执行runtime,支持跨语言代码执行强大的调度器,支持基于低代码以及yaml模式通过appbuilder使用低代码或者js框架开发面向数据的dashboards智能依赖以......
  • CodeForces 838D Airplane Arrangements
    洛谷传送门CF传送门考虑加入第\(n+1\)个位置,这样座位构成了一个环。每个位置被覆盖的概率相等,为\(\frac{m}{n+1}\),然后算出概率再乘方案数就行了。code//Problem:D.AirplaneArrangements//Contest:Codeforces-IndiaHacks2ndElimination2017(unofficial,......
  • 计分牌Scoreboarding代码实现(Python)
    代码地址:Scoreboarding:计算机体系结构作业——计分板模拟(gitee.com)简介此代码为高级计算机体系结构作业——计分板模拟器,使用python实现;模拟的CPU只有四个阶段,分别是发出指令(Issue)、读操作数(ReadOperator,RO)、执行计算(ExecuteComputation,EC)、写结果(WriteResult,WR)......
  • CF838D Airplane Arrangements 题解
    题意一架飞机有\(n\)个座位排成一列,有\(m\)名乘客(\(m\leqn\))依次上飞机。乘客会选择一个目标座位(两人可以选同一个目标座位),然后选择从前门或者后门上飞机,上飞机后,他们会走到自己的目标座位,如果目标座位已经有人坐了,他们会继续往前走,在走到第一个空位后坐下。如果走到最后......
  • Codeforces 1621H - Trains and Airplanes
    这能3500?对于一组在\(u\)上的询问,考虑每种线路\(x\),假设\(1\tou\)路径上线路\(x\)的长度为\(len\),那么不难发现收罚款的次数只有两种可能:\(\lfloor\dfrac{len}{T}\rfloor\)或者\(\lfloor\dfrac{len}{T}\rfloor+1\),且对于一个\(v\)满足\(z_u=z_v\)且\(v\)在\(u......