2022牛客(4)1007_线段树
1007_Climb Stairs_线段树
题目大意:
有0到n的n+1层楼,除了0层其他每层都有一只血量为ai的怪兽。初始攻击力为a0,攻击力大于等于怪兽血量就可以打败怪兽,打败之后就可以将其血量累加到自身攻击力上。每次都可以选择向下走一层或者在i+1到i+k层中选择一层直接跳过去。问是否可以杀死所有的怪兽。
思路和代码:
从一层楼跳上去的时候,中间没打完的怪兽要一个个退回来打掉。打完之后再跳出去。假设现在站在第i层要向上跳,那么就是说i层以下的所有怪兽都被打败了所以当前力量值为[0,i]的前缀和。如果要跳到r层那么就要满足下图的条件:

所以就用线段树维护区间的ai+pi即可判断是否能跳。
int n , m , k ;
ll a[N] ;
ll p[N] ;
struct Node{
int l , r ;
ll val ;
}tr[N << 2] ;
void pushup(int now){
tr[now].val = max(tr[now << 1].val , tr[now << 1 | 1].val) ;
}
void build(int now , int l , int r){
tr[now] = { l , r } ;
if(l == r){
tr[now].val = a[l] + p[l] ; return ;
}int mid = l + r >> 1 ;
build(now << 1 , l , mid) ;
build(now << 1 | 1 , mid + 1 , r) ;
pushup(now) ;
}
ll query(int now , int l , int r){
if(l <= tr[now].l && tr[now].r <= r) return tr[now].val ;
int mid = tr[now].l + tr[now].r >> 1 ;
ll res = -INF ;
if(l <= mid) res = max(res , query(now << 1 , l , r)) ;
if(mid < r ) res = max(res , query(now << 1 | 1 , l , r)) ;
return res ;
}
string solve(){
cin >> n >> a[0] >> k ;
rep(i , 1 , n) cin >> a[i] ;
p[0] = a[0] ;
rep(i , 1 , n) p[i] = a[i] + p[i - 1] ;
build(1 , 1 , n) ;
int i = 0 ;
while(i < n){
int l = i + 1 ;
bool flag = 0 ;
for(int r = l ; r <= n && r <= i + k ; r ++ ){
ll res = query(1 , l , r) ;
if(p[i] >= res - p[r]){
i = r ;
flag = 1 ;
break ;
}
}
if(!flag) break ;
}
return i >= n ? "YES\n" : "NO\n" ;
}//code_by_tyrii
小结
说实话难度不大,把区间的划分做的仔细一点就可以得出结论

浙公网安备 33010602011771号