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

题目描述
andy又开始种树了,他觉得老用魔法不太好,这次他决定老老实实地每天种一棵树,第i天种一颗高度为hi的树,按理说老老实实种树就完事了,哪有那么多问题呢?但是他们学校有个叫kotori的人,非常爱砍树,每天都会把所有andy已经种下的树砍掉ci,如果第i天的时候某棵树的高度已经小于等于ci了,那么这棵树就会死亡,以后再也不会被砍了。并且如果到了第n天,有一些树还没被砍,那么kotori就会在第n + 1天把这些树全部砍死。

输入描述:
第一行输入一个整数n,表示andy会种n天的树。

第二行含有n个数hi,表示andy在第i天种的树的高度为hi米。

第三行含有n个ci,表示kotori在第i天把所有andy已经种下的树砍掉ci。
1 <= n, hi, ci <= 105
输出描述:
输出一行n个数di,每个数后面有一个空格(包括最后一个数),最后需要换行。

表示andy第i天种的树会在第di天死亡,如果第n天这棵树还没有死亡,则输出n + 1。

我们可以做一个假设:每颗树都是第一天种的,在第i天还剩下a[i]高,那么每棵树的初始高度即为a[i]+s[i-1] (s是b的前缀和),那么只要对前缀和二分每颗树在第一天种下,在第几天会被砍光即可

    #include<bits/stdc++.h>
    using namespace std;
    #define PB push_back
    #define LL long long
    #define FI first
    #define SE second
    #define POP pop_back()
    #define PII pair<LL,LL>
    #define PCC pair<char,char>
    #define endl '\n'
    #define ls x<<1
    #define rs x<<1|1
    #define m(x) a[x].l+a[x].r>>1
    
    const int N=1e6+7;
    const int INF=1e8,mod=109;
    
    int n;
    LL a[N];
    LL b[N];
    LL s[N];
    
    int main()
    {
        cin>>n;
        for(int i=1;i<=n;i++){
            scanf("%lld",&a[i]);
        }
        for(int i=1;i<=n;i++){
            scanf("%lld",&b[i]);
            s[i]=s[i-1]+b[i];
        }
        for(int i=1;i<=n;i++){
            LL ans;
            if(a[i]+s[i-1]>s[n]){
                ans=n+1;
            }
            else{
                ans=lower_bound(s+1,s+1+n,a[i]+s[i-1])-s;
            }
            printf("%lld%c",ans,i==n?'\n':' ');
        }
        return 0;
    }