首页 > 其他分享 >归并分治_小和问题

归并分治_小和问题

时间:2024-07-27 23:26:05浏览次数:17  
标签:归并 int 分治 arr 问题 static 数组 new public

归并分治

原理:

1)思考一个问题在大范围上的答案,是否等于,左部分的答案 + 右部分的答案 + 跨越左右产生的答案

2)计算“跨越左右产生的答案”时,如果加上左、右各自有序这个设定,会不会获得计算的便利性

3)如果以上两点都成立,那么该问题很可能被归并分治解决

4)求解答案的过程中只需要加入归并排序的过程即可,因为要让左、右各自有序,来获得计算的便利性

1.小和问题

测试链接 : https://www.nowcoder.com/practice/edfe05a1d45c4ea89101d936cac32469

描述

数组小和的定义如下:

∑i=1nfi ∑i=1nfi (其中 fi f**i 的定义是第 i 个数的左侧小于等于 si s**i 的个数)

例如,数组 s = [1, 3, 5, 2, 4, 6] ,在 s[0] 的左边小于或等于 s[0] 的数的和为 0 ; 在 s[1] 的左边小于或等于 s[1] 的数的和为 1 ;在 s[2] 的左边小于或等于 s[2] 的数的和为 1+3=4 ;在 s[3] 的左边小于或等于 s[3] 的数的和为 1 ;

在 s[4] 的左边小于或等于 s[4] 的数的和为 1+3+2=6 ;在 s[5] 的左边小于或等于 s[5] 的数的和为 1+3+5+2+4=15 。所以 s 的小和为 0+1+4+1+6+15=27

给定一个数组 s ,实现函数返回 s 的小和

数据范围:0<n≤10^5 0<n≤10^5 , ∣si∣≤100

输入描述:

第一行有一个整数N。表示数组长度
接下来一行N个整数表示数组内的数

输出描述:

一个整数表示答案

示例:

输入:

6
1 3 5 2 4 6

输出:

27

备注:

1⩽N⩽10^5
−100⩽arr[i]⩽100

解答:

小和 = 左半部分的小和 + 右半部分的小和 + 左半部分对右半部分的小和

当左右都分别有序时,sum(左侧对右侧某数的小和) 会一直向右滑动而不会返回,sum累加后面的数即可

ans (右侧所有数在左侧的小和之和) = 每一个sum累加和

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 {

	public static int MAXN = 100001;

	public static int[] arr = new int[MAXN];// 进行操作的数组

	public static int[] help = new int[MAXN];// 辅助数组

	public static int n;// 数组中的有效个数

	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 = (int) in.nval;
			for (int i = 0; i < n; i++) {
				in.nextToken();
				arr[i] = (int) in.nval;
			}
			out.println(smallSum(0, n - 1));
		}
		out.flush();
		out.close();
	}

	// 结果比较大,用int会溢出的,所以返回long类型
	// 特别注意溢出这个点,笔试常见坑
	// 返回arr[l...r]范围上,小和的累加和,同时把arr[l..r]变有序
	// 时间复杂度O(n * logn)
	public static long smallSum(int l, int r) {
		if (l == r) {// base case
			return 0;
		}
		int m = (l + r) / 2;
		return smallSum(l, m) + smallSum(m + 1, r) + merge(l, m, r);
	}

	// 返回跨左右产生的小和累加和,左侧有序、右侧有序,让左右两侧整体有序
	// arr[l...m] arr[m+1...r]
	public static long merge(int l, int m, int r) {
		// 统计部分
		long ans = 0;
		for (int j = m + 1, i = l, sum = 0; j <= r; j++) {// 确保每一个右半部分的数都计算到
			while (i <= m && arr[i] <= arr[j]) {// 控制左半部分的指针
				sum += arr[i++];// sum为j位置的数在左半部分的小和
			}
			ans += sum;// ans为所有右半部分的数的小和之和
		}
		// 正常merge 使其有序
		int i = l;// help数组要放置的位置 [l ... r ]
		int a = l;
		int b = m + 1;
		while (a <= m && b <= r) {
			help[i++] = arr[a] <= arr[b] ? arr[a++] : arr[b++];
		}
		while (a <= m) {// 如果左半部分还有数
			help[i++] = arr[a++];
		}
		while (b <= r) {// 如果右半部分还有数
			help[i++] = arr[b++];
		}
		for (i = l; i <= r; i++) {// 从辅助数组中复制到原数组
			arr[i] = help[i];
		}
		return ans;// 返回结果
	}

}

标签:归并,int,分治,arr,问题,static,数组,new,public
From: https://blog.csdn.net/kiddkid/article/details/140730816

相关文章

  • 如何解决用socket实现通讯,即使服务器与客户端链接得到客户端信息却仍报错的问题?
     以上分别是服务器和客户端的代码展示,方便后续大家对运行结果的了解 可以发现当服务器与客户端连接时,客户端的信息已经被服务器接收到了,但仍然报错。此时 可以调用shutdownOutput(),关闭输出流,使服务器端口得到-1值,从而关闭流。目的是告知服务器信息已经输出完毕。再次......
  • 【MySQL】MySQL基础知识:什么是主键?什么是外键?主键和外键有什么区别?外键有什么问题?
    在关系型数据库系统中,如MySQL,主键(PrimaryKey)和外键(ForeignKey)是两个基本且重要的概念,它们在数据库设计和数据维护中扮演着重要的角色。本文将从主键和外键的基本概念入手,详细解析它们之间的区别,并探讨外键在实际应用中可能遇到的问题。......
  • C141 线段树分治+线性基 P3733 [HAOI2017] 八纵八横
    视频链接:C141线段树分治+线性基P3733[HAOI2017]八纵八横_哔哩哔哩_bilibili   P3733[HAOI2017]八纵八横-洛谷|计算机科学教育新生态(luogu.com.cn)//线段树分治+线性基O(q*logq*logL*logL)#include<iostream>#include<cstring>#include<algorithm>......
  • 收藏多年的线程安全问题大全笔记(1),笔记一生一起走,那些日子不再有
    本篇会加入个人的所谓鱼式疯言❤️❤️❤️鱼式疯言:❤️❤️❤️此疯言非彼疯言而是理解过并总结出来通俗易懂的大白话,小编会尽可能的在每个概念后插入鱼式疯言,帮助大家理解的.......
  • 关于函数式弹窗组件遇到的问题
    好久没写博客了。其实也不是没写,只是没发布到的网上。这回记录一个在开发函数式组件中碰到的问题。开门还是不要见山起因是这样的,入职现在这家公司后,发现有些代码习惯挺不适合我的,就是不习惯,没事那就折腾嘛。所以就有了接下来的故事。废两句话,首先说碰到什么问题呢?公司组件......
  • 易优cms 安装常见问题汇总 Eyoucms快速入门
    安装报错,请仔细核对数据库账号和密码答:请检查填写的数据库链接信息是否正确,此问题都是填写的数据库地址,账号,密码不正确导致的本地测试正常,放到虚拟主机就这样了安装的时候出现这个:虚拟主机HPH5.5 ,数据库MYSQL 5.6PHP Warning:  include_once(./templates/step1.php......
  • 代码随想录算法训练营第48天 | 序列问题最终篇
    115.不同的子序列https://leetcode.cn/problems/distinct-subsequences/description/代码随想录https://programmercarl.com/0115.不同的子序列.html#算法公开课https://leetcode.cn/problems/delete-operation-for-two-strings/description/https://programmercarl.com/05......
  • 代码随想录||day25 非递减子序列,全排列问题
    491非递减子序列力扣题目链接题目描述:给你一个整数数组 nums ,找出并返回所有该数组中不同的递增子序列,递增子序列中 至少有两个元素 。你可以按 任意顺序 返回答案。数组中可能含有重复元素,如出现两个整数相等,也可以视作递增序列的一种特殊情况。示例1:输入:nums=......
  • 记一次用户因安全加固后导致SSH登录不上问题
    背景:用户请了安全厂家对大约5台机器(Ubuntu系统)进行了安全加固后无法通过堡垒机等SSH访问链接到机器上,给出以下SSH不上主机图片 处理过程:在向用户拿到root账号密码信息后,通过VNC能够正常登录,则说明root密码是正确的,但进行ssh建立链接时,依然提示账号密码有误链接不上,于是查看/v......
  • 2024AGI面试官 常问的问题以及答案(附最新的AI大模型算法面试大厂必考100题 )
    前言在这个人工智能飞速发展的时代,AI大模型已经成为各行各业创新与变革的重要驱动力。从自动驾驶、医疗诊断到金融分析,AI大模型的应用场景日益广泛,为我们的生活带来了前所未有的便捷。作为一名程序员,了解并掌握AI大模型的相关知识,无疑将大大提升我们的竞争力。在这个充满......