Fast Arrangement (线段树 维护区间最大值 lazy标记)

Fast Arrangement

题意:

有一列火车同一时刻只能承载K个人,然后有Q个人要买票(给出Q组区间表示要买票的区间),(注意: 火车行驶区间为a-b的范围),问那个人可以成功买到票(先到先得)。
解:
利用线段树维护区间最大值,并查询,要注意的是维护的区间(假如你购买的是区间a-区间b,你需要维护的是区间a-区间b-1,因为到端点b的时候你将会下车,下个人可以购其其它的人可以购买)
AC代码:

#include <iostream>
#include <stdio.h>
#define ll long long
#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
#define il inline
using namespace std;
const ll MAXN = 1e6 + 10;
struct Tree {//定义结构
    ll lazy;
    ll maxn;
} t[MAXN<<2];
il void push_up(ll rt) { //向上更新
    t[rt].maxn = max(t[rt << 1].maxn ,t[rt << 1 | 1].maxn);
}
il void push_down(ll rt, ll m) {//pushdown函数
    if(t[rt].lazy) { //若有标记,则将标记向下移动一层
        t[rt << 1].lazy += t[rt].lazy;
        t[rt << 1 | 1].lazy += t[rt].lazy;
        t[rt << 1].maxn += t[rt].lazy;
        t[rt << 1 | 1].maxn+= t[rt].lazy;
        t[rt].lazy = 0;//取消本层标记
    }
}
il void build(ll l,ll r, ll rt) { //建树
    t[rt].lazy = 0;
    if(l == r) {
        t[rt].maxn=0;
        return;
    }
    ll mid = (l + r) >> 1;
    build(lson);
    build(rson);
    push_up(rt);//向上更新
}
il void update(ll L,ll R, ll l,ll r, ll rt) { //区间更新
    if(L <= l && R >= r) {
        t[rt].maxn+=1;
        t[rt].lazy+=1;
        return;
    }
    push_down(rt, r - l + 1);//向下更新
    long long int mid = (l + r) >> 1;
    if(L <= mid) update(L, R,lson);
    if(R > mid) update(L, R,rson);
    push_up(rt);//向上更新
}
il ll query_max(ll L, ll R, ll l, ll r,ll rt) { //区间求最大值
    if(L <= l && R >= r) return t[rt].maxn;
    push_down(rt, r - l + 1);//向下更新
    ll mid = (l + r) >> 1;
    ll ans = 0;
    if(L <= mid) ans = max(ans,query_max(L, R, lson));
    if(R > mid) ans = max(ans,query_max(L, R, rson));
    return ans;
}
int main() {
    ll k,l,r,v,m;
    char a;
    int t;
    cin>>t;
    for(ll i=1; i<=t; i++) {
        printf("Case %lld:\n",i);
        build(1,1000000, 1);
        scanf("%lld %lld", &k,&m);
        for(ll j=1;j<=m;j++) {
            scanf("%lld %lld", &l,&r);
            if(query_max(l,r-1,1,1000000,1)<k){
                    printf("%lld ",j);
                update(l,r-1,1,1000000,1);
            }
        }
        printf("\n\n");
    }
    return 0;
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值