然而仙人的法术也是有局限性的,山势连绵起伏,法术并不能直接把山移走。每次施法,可以把一段连续区域的山头移走相同高度。现在愚公想知道什么时候会有至少一个山头高度小于等于0
给出一个长度为
第一行两个数和
,表示山头数量和施法次数。
第二行个数,分别表示
,即第一个山头到第
个山头的高度。
接下来m行,每行三个数,表示一次施法的具体参数。
,均为整数
输出一个整数,表示答案。数据保证答案存在。
5 4 6 5 3 4 6 1 3 2 4 4 2 3 5 1 1 5 6
3
第一次操作之后山头变成4 3 1 4 6
第二次操作之后山头变成4 3 1 2 6
第三次操作之后山头变成4 3 0 1 5
其中第三个山头高度小于等于了0,可见,在第三次施法之后有一个山头的高度变成了0
import java.util.Arrays;
import java.util.Scanner;
import java.lang.Math;
public class Main {
static class SegmentTree {
int n;
int[] tree;
int[] lazy; // 添加懒惰标记
public SegmentTree(int[] mountains) {
n = mountains.length;
tree = new int[n * 4];
lazy = new int[n * 4];
build(0, 0, n - 1, mountains);
}
public void build(int node, int start, int end, int[] data) {
if (start == end) {
tree[node] = data[start];
return;
}
int mid = (start + end) / 2;
build(node * 2 + 1, start, mid, data);
build(node * 2 + 2, mid + 1, end, data);
tree[node] = Math.min(tree[node * 2 + 1], tree[node * 2 + 2]);
}
// 应用懒惰标记
private void apply(int node, int val) {
tree[node] -= val; // 减去高度
lazy[node] += val;
}
// 下推懒惰标记
private void push(int node) {
if (lazy[node] != 0) {
apply(node * 2 + 1, lazy[node]);
apply(node * 2 + 2, lazy[node]);
lazy[node] = 0;
}
}
public void update(int l, int r, int val) {
update(0, 0, n - 1, l, r, val);
}
private void update(int node, int start, int end, int l, int r, int val) {
// 当前区间完全在更新区间内
if (l <= start && end <= r) {
apply(node, val); // 直接更新并记录懒惰标记
return;
}
push(node); // 下推懒惰标记
int mid = (start + end) / 2;
if (l <= mid) {
update(node * 2 + 1, start, mid, l, r, val);
}
if (r > mid) {
update(node * 2 + 2, mid + 1, end, l, r, val);
}
tree[node] = Math.min(tree[node * 2 + 1], tree[node * 2 + 2]);
}
public int getMin() {
return tree[0]; // 根节点存储全局最小值
}
}
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int times = in.nextInt();
int[] mountains = new int[n];
for (int i = 0; i < n; i++) {
mountains[i] = in.nextInt();
}
SegmentTree st = new SegmentTree(mountains);
for (int i = 1; i <= times; i++) { // 注意:应该是 <= times
int x = in.nextInt();
int y = in.nextInt();
int minus = in.nextInt();
// 转换为0-index,区间[x-1, y-1]
st.update(x - 1, y - 1, minus);
if (st.getMin() <= 0) {
System.out.println(i);
return;
}
}
in.close();
}
} 更新利用线段树的Java代码,部分依靠deepseek进行了修正
public static void main(String[] args) { Scanner in = new Scanner(System.in); int n = in.nextInt(); int m = in.nextInt(); int shuhcu; int [] shan= new int[n]; for(int i=0;i<n;i++){ shan[i]= in.nextInt(); } int [][] cishu= new int[m][3]; for(int i=0;i<m;i++){ cishu[i][0]= in.nextInt(); cishu[i][1]= in.nextInt(); cishu[i][2]= in.nextInt(); } shuhcu=shifa(shan,cishu,m); System.out.print(shuhcu); } static int shifa(int shan[],int shifa[][],int m){ for(int i=0;i<m;i++){ shifacaozuo(shan,shifa[i][0],shifa[i][1],shifa[i][2]); for(int panduan :shan){ if(panduan<=0){ return i+1; } } } return -1; } static void shifacaozuo(int shan[],int L,int R,int H){ for(int j=L-1;j<R;j++){ shan[j]=shan[j]-H; } }
} return -1; } static void shifacaozuo(int shan[],int L,int R,int H){ for(int j=L-1;j<R;j++){ shan[j]=shan[j]-H; } }
import java.util.Scanner;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int m = in.nextInt();
int[] arr = new int[n];
int[] diff = new int[n + 1];
for (int i = 0; i < n; i++) {
arr[i] = in.nextInt();
if (i == 0) {
diff[i] = arr[i];
} else {
diff[i] = arr[i] - arr[i - 1];
}
}
boolean flag = true;
for (int i = 0; flag && i < m; i++) {
int left = in.nextInt();
int right = in.nextInt();
int h = in.nextInt();
diff[left - 1] -= h;
diff[right] += h;
int sum = 0;
for (int j = 0; j < right; j++) {
sum = sum + diff[j];
if (sum <= 0) {
System.out.println(i + 1);
flag = false;
break;
}
}
}
}
} #include <iostream>
#include <vector>
using namespace std;
int main() {
int n,m;
cin>>n>>m;
vector<int> a(n+1);
for(int i=1;i<=n;i++)
cin>>a[i];
int ans=0;
for(int i=0;i<m;i++)
{
int L,R,h;
cin>>L>>R>>h;
if(ans)
continue;
for(int j=L;j<=R;j++)
if((a[j]-=h)<=0)
ans=i+1;
}
cout<<ans<<endl;
return 0;
}