1 条题解

  • 0
    @ 2025-8-24 23:09:48

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar gan_ge
    天下有道,以道殉身。天下无道,以身殉道。

    搬运于2025-08-24 23:09:48,当前版本为作者最后更新于2025-08-07 17:02:00,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    先看测试点 6,76,7:不会在 ti>0t_i>0 时出现 command 操作,此时若以时间 tt 为横坐标,机器人在数轴上的位置 xx 为横坐标绘出机器人的轨迹,易知其为形如 x=kt+bx=kt+b 的一次函数图像。

    但当 ti>0t_i>0 时出现 command 操作时,该轨迹又会变成一条折线,极为不美观,此时若把折线分成若干线段,则每条线段仍满足上面的性质,但有定义域的限制。

    因此考虑离线,将每个机器人的轨迹分为若干线段存储,线段总数为 n+Cn+Cnn 个机器人,每次操作会产生 11 个新的线段)。

    现在题目转化为:

    现有 n+Cn+C 条形如 x=kt+b,t[l,r]x=kt+b,t \in[l,r] 的线段,QQ 次询问,每次给定一个数 tit_i,求与直线 t=tit=t_i 相交的线段中,交点纵坐标最大为多少。

    显然是李超线段树,但交点坐标均为整数,比模版P4097 【模板】李超线段树还是好写点的。

    注意

    1. bb 值可能很大,要开 long long
    2. 0ti1090 \le t_i \le 10^9,故要用动态开点线段树。

    附代码:

    #include<bits/stdc++.h>
    using namespace std;
    
    #define ls tr[p].l
    #define rs tr[p].r
    
    typedef long long ll;
    typedef long double ld;
    
    const int N=1e5+10;
    
    struct line{
        int k;ll b;
    }p[N<<2];
    
    int cnt=0;
    
    ll f(int id,int x){
        return labs(1ll*p[id].k*x+p[id].b);
    }
    
    struct tree{
        int l,r,id;
    }tr[N<<5];
    
    int tot=0,rt=0;
    
    void pushnow(int &p,int l,int r,int now){
        if(!p) p=++tot;
        int &lst=tr[p].id,mid=(l+r)>>1;
        if(f(now,mid)>f(lst,mid)) swap(now,lst);
    
        if(f(now,l)>f(lst,l)) pushnow(ls,l,mid,now);
        if(f(now,r)>f(lst,r)) pushnow(rs,mid+1,r,now);
    }
    
    void update(int &p,int l,int r,int ql,int qr,int now){
        if(!p) p=++tot;
        if(ql<=l&&r<=qr) return pushnow(p,l,r,now),void();
        int mid=(l+r)>>1;
        if(ql<=mid) update(ls,l,mid,ql,qr,now);
        if(qr>mid) update(rs,mid+1,r,ql,qr,now);
    }
    
    ll query(int p,int l,int r,int pl){
        if(!p) return 0;
        ll res=f(tr[p].id,pl);
        int mid=(l+r)>>1;
        if(pl<=mid) return max(res,query(ls,l,mid,pl));
        else return max(res,query(rs,mid+1,r,pl));
    }
    
    int n,m,mxt=0,a[N];
    
    vector<pair<int,int> > ch[N];
    
    vector<int> q;
    
    int main(){
        ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
        cin>>n>>m;
        for(int i=1;i<=n;i++){
            cin>>a[i];
            ch[i].push_back({0,0});
        }
        int t,k,x; string s;
        for(int i=1;i<=m;i++){
            cin>>t>>s;
            mxt=max(mxt,t);
            if(s[0]=='c'){
                cin>>k>>x;
                if((*ch[k].rbegin()).first==t) ch[k].pop_back();
                ch[k].push_back({t,x});
            }
            else q.push_back(t);
        }
        for(int i=1;i<=n;i++){
            if((*ch[i].rbegin()).first!=mxt) ch[i].push_back({mxt,0});
            ll y=a[i];
            for(int j=1;j<(int)ch[i].size();j++){
                int l=ch[i][j-1].first,r=ch[i][j].first,k=ch[i][j-1].second;
                p[++cnt]={k,y-1ll*k*l};
                y+=1ll*(r-l)*k;
                update(rt,0,mxt,l,r,cnt);
            }
        }
        for(auto i:q)
            cout<<query(1,0,mxt,i)<<'\n';
        return 0;
    }
    
    • 1

    信息

    ID
    11495
    时间
    1000ms
    内存
    256MiB
    难度
    6
    标签
    递交数
    0
    已通过
    0
    上传者