1 条题解
-
0
自动搬运
来自洛谷,原作者为

hzoi_Shadow
不就是一次考试吗,以后谁闲的没事,翻你档案再查你成绩——波波搬运于
2025-08-24 22:51:57,当前版本为作者最后更新于2023-11-05 13:28:24,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
前置知识
解法
第一眼感觉和 luogu P1083 [NOIP2012 提高组] 借教室 很像。本题同样采用线段树维护, 表示从 时刻内骑士拜访的总时间, 表示从 时刻内骑士拜访完的最后时间。
build 函数和普通线段树一样。
update 函数和普通单点修改一样。
- 如果不会线段树单点修改,请左转 luogu P3374 【模板】树状数组 1。
pushup 函数是本题一个难点。考虑对于从 时刻,如果左区间 时刻骑士拜访完的最后时间大于右区间 时刻的起始点,则右区间 时刻内所有骑士拜访均要向后推迟,即
tree[rt].maxx=max(tree[lson(rt)].maxx+tree[rson(rt)].sum,tree[rson(rt)].maxx);。query 函数同理,查询时需要额外记录左区间 时刻骑士拜访完的最后时间,对于最终时间时需要取 ,即
max(tree[rt].maxx,tree[rt].sum+maxxx);。最终答案即为最终时间减去起始拜访时间。代码
#include<bits/stdc++.h> using namespace std; #define ll long long//本题需要开 long long #define sort stable_sort #define endl '\n' ll t[400000],d[400000],ans=0; struct SegmentTree { ll l,r,sum,maxx; }tree[5000000]; ll lson(ll x) { return x*2; } ll rson(ll x) { return x*2+1; } void pushup(ll rt) { tree[rt].sum=tree[lson(rt)].sum+tree[rson(rt)].sum; tree[rt].maxx=max(tree[lson(rt)].maxx+tree[rson(rt)].sum,tree[rson(rt)].maxx); } void build(ll rt,ll l,ll r) { tree[rt].l=l; tree[rt].r=r; if(l==r) { tree[rt].maxx=tree[rt].sum=0; return; } ll mid=(l+r)/2; build(lson(rt),l,mid); build(rson(rt),mid+1,r); pushup(rt); } void update(ll rt,ll pos,ll val) { if(tree[rt].l==tree[rt].r) { tree[rt].sum=val; tree[rt].maxx=tree[rt].l+val; return; } else { ll mid=(tree[rt].l+tree[rt].r)/2; if(pos<=mid) { update(lson(rt),pos,val); } else { update(rson(rt),pos,val); } } pushup(rt); } ll query(ll rt,ll l,ll r,ll maxxx) { if(l<=tree[rt].l&&tree[rt].r<=r) { return max(tree[rt].maxx,tree[rt].sum+maxxx); } else { ll mid=(tree[rt].l+tree[rt].r)/2; if(l<=mid) { ans=max(ans,query(lson(rt),l,r,maxxx)); } if(mid<r) { ans=max(ans,query(rson(rt),l,r,ans)); } return ans; } } int main() { ll q,n,i,val; char pd; cin>>q; build(1,1,1000000); for(i=1;i<=q;i++) { cin>>pd; if(pd=='+') { cin>>t[i]>>d[i]; update(1,t[i],d[i]);//因为第i位骑士访谈的时间是t[i]到t[i]+d[i] } if(pd=='-') { cin>>val; update(1,t[val],0); } if(pd=='?') { cin>>val; ans=0; cout<<max(0ll,query(1,1,val,ans)-val)<<endl; } } return 0; }后记
双倍经验:P9801 | CF1089K
- 1
信息
- ID
- 8905
- 时间
- 2600ms
- 内存
- 512MiB
- 难度
- 6
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者