T2 诺亚方舟
吐槽:题目的坑好离谱……
本题是线段树区间修改,区间查询的题目
题目中说优先搭载买票先的奶牛,所以一头奶牛上不了车可以直接放弃,无需考虑次序问题。
每一头奶牛上车以后都会增加 111 个当前载客量,所以我们用 ansians_{i}ansi
表示列车到达第 iii 个站点的剩余载客量,初始值都为 kkk ,一旦奶牛所经过的某个站点满载(ansians_{i}ansi 等于 000 )当前奶牛就无法上车。
每次给定奶牛的起点和终点,如果使用朴素做法从起点到终点枚举将奶牛经过的站点剩余载客量 −1-1−1 就会超时(50pts\text{50pts}50pts ),所以我们考虑用线段树维护区间内剩余载客量最小值并做每一次的修改。
每次读入 aaa 和 bbb 时 query\text{query}query 一次,将 ansaans_{a}ansa ~ ansb−1ans_{b-1}ansb−1 (坑点:奶牛下车以后不会占用载客量,所以终点的剩余载客量不用减)
若最小值小于等于 000 ,则当前奶牛不能上车,直接放弃
若最小值大于 000 ,则当前奶牛上车,并将 ansaans_{a}ansa ~ ansb−1ans_{b-1}ansb−1 中的每个数加 111 (update\text{update}update 函数),表示该站点的载客量 +1+1+1 。
最后注意输出格式等就能 $\text{AC} $ 了。
Tips\text{Tips}Tips : 由于行末不能有空格,可以将答案储存到一个答案数组后输出。
Coding Time\text{Coding Time}Coding Time
#include<bits/stdc++.h>
using namespace std;
int sum[4000005],ans[4000005],n,T,m,x[1000005],y[1000005],s[1000005],xb;
void push_down(int p)
{
if(sum[p])
{
ans[p<<1]+=sum[p];
ans[p<<1|1]+=sum[p];
sum[p<<1]+=sum[p];
sum[p<<1|1]+=sum[p];
sum[p]=0;
}
}
void update(int p,int l,int r,int ql,int qr)
{
if(ql<=l&&r<=qr)
{
ans[p]--;//将当前剩余载客量-1
sum[p]--;//懒人标记也要-1
return;
}
push_down(p);//标记下传
int mid=l+r>>1;
if(ql<=mid)
update(p<<1,l,mid,ql,qr);
if(mid<qr)
update(p<<1|1,mid+1,r,ql,qr);
ans[p]=min(ans[p<<1],ans[p<<1|1]);
}
int query(int p,int l,int r,int ql,int qr)
{
if(ql<=l&&r<=qr)
return ans[p];
push_down(p);
int mid=l+r>>1;
int mn=2e9;
if(ql<=mid)
mn=min(mn,query(p<<1,l,mid,ql,qr));
if(qr>mid)
mn=min(mn,query(p<<1|1,mid+1,r,ql,qr));
return mn;
}
int main()
{
cin>>T;
for(int whxakioi=1;whxakioi<=T;++whxakioi)
{
xb=0;//清空答案数组
cout<<"Case "<<whxakioi<<":\n";
cin>>n>>m;
int mx=0;
for(int i=1;i<=m;++i)
{
cin>>x[i]>>y[i];
--y[i];//一开始就将终点-1,如上所述
mx=max(mx,y[i]);//求出下车点最大值
}
for(int i=1;i<=mx*4;++i)//初值
ans[i]=n,sum[i]=0;
for(int i=1;i<=m;++i)
{
if(query(1,1,mx,x[i],y[i])>0)//若区间最小值大于0,则奶牛可以上车
{
s[++xb]=i;//记录到答案数组中
update(1,1,mx,x[i],y[i]);//区间修改
}
}
if(xb==0)
cout<<"\n\n";//输出两个换行
for(int i=1;i<=xb;++i)
if(i==xb)
cout<<s[i]<<"\n\n";else
cout<<s[i]<<' ';
}
}
本文介绍了如何运用线段树解决一道区间修改与查询的编程题目,强调了奶牛上车问题的处理细节,包括区间最小值的查询与更新操作,以及如何避免超时。通过案例解析了线段树在动态维护区间信息中的应用,并给出了完整的C++代码实现。

被折叠的 条评论
为什么被折叠?



