当前位置: 首页 > article >正文

【洛谷】5026、Lycanthropy 落水后水的高度

【洛谷】5026、Lycanthropy 落水后水的高度

文章目录

  • 一、等差数列差分
    • 1.1 等差数列差分
  • 二、多语言解法

一、等差数列差分

1.1 等差数列差分

// java
// 一群人落水后求每个位置的水位高度
// 问题描述比较复杂,见测试链接
// 测试链接 : https://www.luogu.com.cn/problem/P5026
// 请同学们务必参考如下代码中关于输入、输出的处理
// 这是输入输出处理效率很高的写法
// 提交以下的code,提交时请把类名改成"Main",可以直接通过

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;

public class Main {

	// 题目说了m <= 10^6,代表湖泊宽度
	// 这就是MAXN的含义,湖泊最大宽度的极限
	public static int MAXN = 1000001;

	// 数值保护,因为题目中v最大是10000
	// 所以左侧影响最远的位置到达了x - 3 * v + 1
	// 所以右侧影响最远的位置到达了x + 3 * v - 1
	// x如果是正式的位置(1~m),那么左、右侧可能超过正式位置差不多30000的规模
	// 这就是OFFSET的含义
	public static int OFFSET = 30001;

	// 湖泊宽度是MAXN,是正式位置的范围
	// 左、右侧可能超过正式位置差不多OFFSET的规模
	// 所以准备一个长度为OFFSET + MAXN + OFFSET的数组
	// 这样一来,左侧影响最远的位置...右侧影响最远的位置,
	// 都可以被arr中的下标表示出来,就省去了很多越界讨论
	// 详细解释看set方法的注释
	public static int[] arr = new int[OFFSET + MAXN + OFFSET];

	public static int n, m;

	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StreamTokenizer in = new StreamTokenizer(br);
		PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
		while (in.nextToken() != StreamTokenizer.TT_EOF) {
			// n有多少个人落水,每个人落水意味着四个等差数列操作
			n = (int) in.nval;
			in.nextToken();
			// 一共有多少位置,1~m个位置,最终要打印每个位置的水位
			m = (int) in.nval;
			for (int i = 0, v, x; i < n; i++) {
				in.nextToken(); v = (int) in.nval;
				in.nextToken(); x = (int) in.nval;
				// v体积的朋友,在x处落水,修改差分数组
				fall(v, x);
			}
			// 生成最终的水位数组
			build();
			// 开始收集答案
			// 0...OFFSET这些位置是辅助位置,为了防止越界设计的
			// 从OFFSET+1开始往下数m个,才是正式的位置1...m
			// 打印这些位置,就是返回正式位置1...m的水位
			int start = OFFSET + 1;
			out.print(arr[start++]);
			for (int i = 2; i <= m; i++) {
				out.print(" " + arr[start++]);
			}
			out.println();
		}
		out.flush();
		out.close();
		br.close();
	}

	public static void fall(int v, int x) {
		set(x - 3 * v + 1, x - 2 * v, 1, v, 1);
		set(x - 2 * v + 1, x, v - 1, -v, -1);
		set(x + 1, x + 2 * v, -v + 1, v, 1);
		set(x + 2 * v + 1, x + 3 * v - 1, v - 1, 1, -1);
	}

	public static void set(int l, int r, int s, int e, int d) {
		// 为了防止x - 3 * v + 1出现负数下标,进而有很多很烦的边界讨论
		// 所以任何位置,都加上一个较大的数字(OFFSET)
		// 这样一来,所有下标就都在0以上了,省去了大量边界讨论
		// 这就是为什么arr在初始化的时候要准备OFFSET + MAXN + OFFSET这么多的空间
		arr[l + OFFSET] += s;
		arr[l + 1 + OFFSET] += d - s;
		arr[r + 1 + OFFSET] -= d + e;
		arr[r + 2 + OFFSET] += e;
	}

	public static void build() {
	    // 从1到m+OFFSET的范围, 其实多求了一些数, 但无所谓, 这样是害怕漏了.
	    // 最终打印结果时, 只从 OFFSET+1 向后数m个数即可
		for (int i = 1; i <= m + OFFSET; i++) {
			arr[i] += arr[i - 1];
		}
		for (int i = 1; i <= m + OFFSET; i++) {
			arr[i] += arr[i - 1];
		}
	}
}

左神 视频 等差数列差分

二、多语言解法

C p p / G o / P y t h o n / R u s t / J s / T s Cpp/Go/Python/Rust/Js/Ts Cpp/Go/Python/Rust/Js/Ts

// cpp
// go 同上
# python
// rust
// js
// ts

http://www.kler.cn/a/465022.html

相关文章:

  • 23. 【.NET 8 实战--孢子记账--从单体到微服务】--记账模块--预算
  • Fabric链码部署测试
  • 无刷直流电机(BLDC)六步换向法
  • 《Swift 结构体》
  • 【2025最新计算机毕业设计】基于Spring Boot+Vue影院购票系统(高质量源码,提供文档,免费部署到本地)
  • 【C#深度学习之路】如何使用C#实现Yolo5/8/11全尺寸模型的训练和推理
  • php获取字符串中的汉字
  • 图书项目:整合SSM
  • C++软件设计模式之解释器模式
  • 高职人工智能数据工程技术专业教学解决方案(2025年新专业)
  • 【每日学点鸿蒙知识】RelativeContainer组件、List回弹、Flutter方法调用、Profiler工具等
  • logback之配置文件使用详解
  • 使用 Bash 脚本中的time命令来统计命令执行时间:中英双语
  • 【开源社区openEuler实践】A-ops
  • OCP 认证专家零基础小白
  • Ruby自动化:用Watir库获取YouTube视频链接
  • 【Git系列】Git 分支操作:`git checkout -b test`与`git checkout test`的区别
  • OpenGL变换矩阵和输入控制
  • Linux---自动化工具Ansible模块教程
  • Go gin框架(详细版)
  • 【Triton-ONNX】如何使用 ONNX 模型服务与 Triton 通信执行推理任务上-Triton快速开始
  • 【Vue】<script setup>和 <script>区别是什么?在使用时的写法区别?
  • flutter组件————Row和Column
  • 【sql】CAST(GROUP_CONCAT())实现一对多对象json输出
  • 办公 三之 Excel 数据限定录入与格式变换
  • 机器学习-感知机-神经网络-激活函数-正反向传播-梯度消失-dropout