1014 迪拜的超市 思维 二分 线段树 清空

 链接:https://ac.nowcoder.com/acm/contest/26896/1014
来源:牛客网

题目描述

forever97家住迪拜一环,因此有很多大大小小的商场。
迪拜一环有n个超市,分别在坐标轴[1,n]位置,forever97家在0这个位置。
由于日常开销巨大,所以Trote_w经常让forever97出去买东西。
假如forever97现在要买k件物品,他会从第一家超市开始买东西,买完第一家之后向右走,直到买完k件物品为止。
在开始的时候,每个商店都是0个物品。
有以下两种操作:
1 l r x:代表[l,r]这个区间的超市都购入了x件物品
2 k:代表forever97要买入k个物品(注意:买完之后每个商店的商品会减少被购买的数量)
现在forever97想知道对于每个2操作,他走到哪个商店才能买完k个物品。

输入描述:

多组数据

第一行一个T(1<=T<=10)代表样例组数

对于每组样例
第一行一个n(1<=n<=100000)代表商店个数,一个q(1<=q<=100000)代表操作次数。
接下来q行
每行为上述1操作或者2操作
1<=l<=r<=n 1<=x<=10000
1<=k<=10
9

输出描述:

对于每个2操作,输出一个数字y,代表forever97走到y商店能买完k件物品。
如果所有超市的物品总和不够k件,那么forever97会放弃这次购买,输出"Trote_w is sb"。
示例1

输入

复制
1
5 6
2 1
1 1 5 5
2 12
2 12
2 12
2 1

输出

复制
Trote_w is sb
3
5
Trote_w is sb
5

分析

函数写的越多,维护起来越容易

题目要求1~x 区间内从前往后依次取出一些物品直到达到 k

可以用二分,如果当前区间的左边有小于 k 个物品,直接把它们清空并往右找就可以了

如果左边物品数大于 k 那继续往左找

sd 的lazy标记表示这一段要不要清空

//-------------------------代码----------------------------

#define int ll
const int N = 1e5+10;
int n,m;

struct node {
    int l,r,s,la;
    bool sd;
}tr[N<<2];

void build(int u,int l,int r) {
    tr[u] = {l,r,0,0};
    if(l == r) {;return;}
    build(ul,l,tr_mid);build(ur,tr_mid+1,r);
}

void push_down(int u) {
    if(tr[u].l == tr[u].r) rt;
    if(tr[u].sd == 1) {
        tr[ul].la = tr[ul].s = 0;
        tr[ul].sd = 1;
        tr[ur].la = tr[ur].s = 0;
        tr[ur].sd = 1;
        tr[u].sd = 0;
    }
    if(tr[u].la) {
        tr[ul].la += tr[u].la;
        tr[ul].s += tr[u].la * tr_len(ul);
        tr[ur].la += tr[u].la;
        tr[ur].s += tr[u].la * tr_len(ur);
        tr[u].la = 0;
    }
}


int query(int u,int l,int r) {
    if(l <= tr[u].l && tr[u].r <= r) return tr[u].s;
    if(tr[u].l > r || tr[u].r < l) return 0;
    push_down(u);
    return query(ul,l,r) + query(ur,l,r);
}

void mo(int u,int l,int r,int c) {
    if(l <= tr[u].l && tr[u].r <= r) {
        tr[u].la += c;
        tr[u].s += c * tr_len(u);
        return;
    }
    push_down(u);
    if(l <= tr_mid) mo(ul,l,r,c);
    if(tr_mid <  r) mo(ur,l,r,c);
    tr[u].s = tr[u<<1].s + tr[ur].s;
}

#define F cout<<"Trote_w is sb"<<endl;
int q;



int find(int u,int k) {
    tr[u].s -= k;
    if(tr[u].l == tr[u].r) return tr[u].l;
    push_down(u);
    if(tr[ul].s < k) {
        k -= tr[ul].s;
        tr[ul].s = tr[ul].la = 0;
        tr[ul].sd = 1;
        return find(ur,k);
    }
    return find(ul,k);
}





void solve()
{
//    cin>>n>>m;
    cin>>n>>q;
    build(1,1,n);
    while(q -- ) {
        int op;cin>>op;
        if(op == 1) {
            int l,r,x;cin>>l>>r>>x;
            mo(1,l,r,x);
        } else {
            int k;cin>>k;
            if(tr[1].s<k) {F}
            else cout<<find(1,k)<<endl;
        }
    }
}
void main_init() {}
signed main(){
    AC();clapping();TLE;
    cout<<fixed<<setprecision(12);
    main_init();
//  while(cin>>n,n)
//  while(cin>>n>>m,n,m)
    int t;cin>>t;while(t -- )
    solve();
//    {solve(); }
    return 0;
}

/*样例区


*/

//------------------------------------------------------------

 

posted @ 2022-08-09 23:35  er007  阅读(51)  评论(0)    收藏  举报