北京信息科技大学第十一届程序设计竞赛(重现赛)J andy的树被砍了
链接: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;
}