2023-09-01:用go语言编写。给出两个长度均为n的数组,

A = { a1, a2, ... ,an },

B = { b1, b2, ... ,bn }。

你需要求出其有多少个区间[L,R]满足:

数组A中下标在[L,R]中的元素之和在[La,Ra]之中,

数组B中下标在[L,R]中的元素之和在[Lb,Rb]之中。

输入:

第一行有一个正整数N(1<=N<=100000),代表两个数组的长度。

第二行有N个非负整数,范围在0到1000000000之间,代表数组中的元素。

第三行有N个非负整数,范围在0到1000000000之间,代表数组中的元素。

第四行有4个整数La,Ra,Lb,Rb,范围在0到10^18之间,代表题目描述中的参数。

输出:

输出一个整数,代表所求的答案。

来自微众银行。

来自左程云。

答案2023-09-01:

大体过程如下:

1.定义两个暴力方法(nums1和nums2)来求解问题。这两个方法的输入参数包括两个数组A和B,数组A的左右边界(la和ra),数组B的左右边界(lb和rb)。

2.方法nums1使用暴力的方法遍历所有可能的区间,并统计满足条件的区间个数。

  • 初始化变量ans为0,表示满足条件的区间个数。

  • 使用两层循环遍历数组A的所有可能区间。外层循环变量l表示区间的左边界,内层循环变量r表示区间的右边界。

  • 对于每个区间,初始化变量sumA和sumB为0,分别表示数组A和数组B中元素之和。

  • 使用一个循环遍历当前区间内的元素,累加sumA和sumB。

  • 判断sumA是否在[la, ra]之间,sumB是否在[lb, rb]之间,如果满足条件则增加ans的值。

  • 返回ans作为结果。

3.方法nums2使用优化的方法来求解问题。

  • 初始化变量ans为0,表示满足条件的区间个数。

  • 初始化变量rightA1、sumA1、rightA2、sumA2、rightB1、sumB1、rightB2、sumB2为0,分别表示数组A和数组B的右边界和元素之和。

  • 使用一个循环遍历数组A的所有可能左边界。循环变量l表示左边界的位置。

  • 在循环中,使用while循环更新rightA1、sumA1、rightA2、sumA2、rightB1、sumB1、rightB2、sumB2,使其满足条件。

  • 计算数组A和数组B的左右交集的左边界left和右边界right。

  • 如果left小于right,则将right减去left的值加到ans中。

  • 根据当前左边界l更新rightA1、sumA1、rightA2、sumA2、rightB1、sumB1、rightB2、sumB2。

  • 返回ans作为结果。

4.定义randomArray方法,用于生成指定长度和范围的随机数组。

  • 输入参数包括数组的长度n和随机数的范围v。

  • 初始化一个长度为n的数组ans。

  • 使用一个循环遍历数组,为每个元素赋一个随机数值。

  • 返回生成的随机数组ans。

5.定义max和min方法,分别用于求两个数的最大值和最小值。

6.在main函数中进行测试。

  • 初始化随机数种子。

  • 定义常量N和V,表示数组的长度和随机数的范围。

  • 定义变量testTimes,表示测试次数。

  • 使用循环进行测试。

  • 在每次测试中,生成随机数组A和B,以及随机的la、ra、lb、rb。

  • 调用nums1和nums2方法,分别得到暴力和优化方法的结果。

  • 比较两个结果,如果不一致则输出错误信息。

  • 完成测试后输出测试结束信息。

总的时间复杂度:

  • 对于方法nums1,需要三重循环遍历数组,时间复杂度为O(n^3)。

  • 对于方法nums2,需要两重循环遍历数组,时间复杂度为O(n^2)。

总的额外空间复杂度:

  • 除了输入参数外,额外使用的空间主要是变量和随机数组。因此,额外空间复杂度为O(n)。

go完整代码如下:

package main

import (
"math/rand"
"fmt"
"time"
) // 暴力方法
func nums1(A []int, B []int, la int, ra int, lb int, rb int) int {
n := len(A)
ans := 0
for l := 0; l < n; l++ {
for r := l; r < n; r++ {
sumA := 0
sumB := 0
for i := l; i <= r; i++ {
sumA += A[i]
sumB += B[i]
}
if sumA >= la && sumA <= ra && sumB >= lb && sumB <= rb {
ans++
}
}
}
return ans
} // 正式方法
func nums2(A []int, B []int, la int, ra int, lb int, rb int) int {
n := len(A)
ans := 0
rightA1, sumA1, rightA2, sumA2 := 0, 0, 0, 0
rightB1, sumB1, rightB2, sumB2 := 0, 0, 0, 0
for l := 0; l < n; l++ {
for rightA1 < n && sumA1+A[rightA1] < la {
sumA1 += A[rightA1]
rightA1++
}
for rightA2 < n && sumA2+A[rightA2] <= ra {
sumA2 += A[rightA2]
rightA2++
}
for rightB1 < n && sumB1+B[rightB1] < lb {
sumB1 += B[rightB1]
rightB1++
}
for rightB2 < n && sumB2+B[rightB2] <= rb {
sumB2 += B[rightB2]
rightB2++
}
left := max(rightA1, rightB1)
right := min(rightA2, rightB2)
if left < right {
ans += right - left
}
if rightA1 == l {
rightA1++
} else {
sumA1 -= A[l]
}
sumA2 -= A[l]
if rightB1 == l {
rightB1++
} else {
sumB1 -= B[l]
}
sumB2 -= B[l]
}
return ans
} func randomArray(n int, v int) []int {
ans := make([]int, n)
for i := 0; i < n; i++ {
ans[i] = rand.Intn(v)
}
return ans
} func max(a int, b int) int {
if a > b {
return a
}
return b
} func min(a int, b int) int {
if a < b {
return a
}
return b
} func main() {
rand.Seed(time.Now().Unix())
N := 50
V := 100
testTimes := 10000
fmt.Println("测试开始")
for i := 0; i < testTimes; i++ {
n := rand.Intn(N)
A := randomArray(n, V)
B := randomArray(n, V)
a := rand.Intn(V)
b := rand.Intn(V)
c := rand.Intn(V)
d := rand.Intn(V)
la := min(a, b)
ra := max(a, b)
lb := min(c, d)
rb := max(c, d)
ans1 := nums1(A, B, la, ra, lb, rb)
ans2 := nums2(A, B, la, ra, lb, rb)
if ans1 != ans2 {
fmt.Println("出错了!")
}
}
fmt.Println("测试结束")
}

rust完整代码如下:

use rand::Rng;

fn nums1(A: &[i32], B: &[i32], la: i32, ra: i32, lb: i32, rb: i32) -> i32 {
let n = A.len();
let mut ans = 0;
for l in 0..n {
for r in l..n {
let mut sum_a = 0;
let mut sum_b = 0;
for i in l..=r {
sum_a += A[i];
sum_b += B[i];
}
if sum_a >= la && sum_a <= ra && sum_b >= lb && sum_b <= rb {
ans += 1;
}
}
}
ans
} fn nums2(A: &[i32], B: &[i32], la: i32, ra: i32, lb: i32, rb: i32) -> i32 {
let n = A.len() as i32;
let mut ans = 0;
let (mut right_a1, mut sum_a1, mut right_a2, mut sum_a2) = (0, 0, 0, 0);
let (mut right_b1, mut sum_b1, mut right_b2, mut sum_b2) = (0, 0, 0, 0);
for l in 0..n {
while right_a1 < n && sum_a1 + A[right_a1 as usize] < la {
sum_a1 += A[right_a1 as usize];
right_a1 += 1;
}
while right_a2 < n && sum_a2 + A[right_a2 as usize] <= ra {
sum_a2 += A[right_a2 as usize];
right_a2 += 1;
}
while right_b1 < n && sum_b1 + B[right_b1 as usize] < lb {
sum_b1 += B[right_b1 as usize];
right_b1 += 1;
}
while right_b2 < n && sum_b2 + B[right_b2 as usize] <= rb {
sum_b2 += B[right_b2 as usize];
right_b2 += 1;
}
let left = right_a1.max(right_b1);
let right = right_a2.min(right_b2);
if left < right {
ans += right - left;
}
if right_a1 == l {
right_a1 += 1;
} else {
sum_a1 -= A[l as usize];
}
sum_a2 -= A[l as usize];
if right_b1 == l {
right_b1 += 1;
} else {
sum_b1 -= B[l as usize];
}
sum_b2 -= B[l as usize];
}
ans
} fn random_array(n: i32, v: i32) -> Vec<i32> {
let mut rng = rand::thread_rng();
(0..n).map(|_| rng.gen_range(0, v)).collect()
} fn main() {
const N: i32 = 50;
const V: i32 = 100;
const TEST_TIMES: usize = 10000;
println!("测试开始");
for _ in 0..TEST_TIMES {
let n = rand::thread_rng().gen_range(0, N);
let A = random_array(n, V);
let B = random_array(n, V);
let a = rand::thread_rng().gen_range(0, V);
let b = rand::thread_rng().gen_range(0, V);
let c = rand::thread_rng().gen_range(0, V);
let d = rand::thread_rng().gen_range(0, V);
let la = a.min(b);
let ra = a.max(b);
let lb = c.min(d);
let rb = c.max(d);
let ans1 = nums1(&A, &B, la, ra, lb, rb);
let ans2 = nums2(&A, &B, la, ra, lb, rb);
if ans1 != ans2 {
println!("出错了!");
}
}
println!("测试结束");
}

c++完整代码如下:

#include <iostream>
#include <vector>
#include <cstdlib> using namespace std; int nums1(vector<int>& A, vector<int>& B, int la, int ra, int lb, int rb) {
int n = A.size();
int ans = 0;
for (int l = 0; l < n; l++) {
for (int r = l; r < n; r++) {
int sumA = 0;
int sumB = 0;
for (int i = l; i <= r; i++) {
sumA += A[i];
sumB += B[i];
}
if (sumA >= la && sumA <= ra && sumB >= lb && sumB <= rb) {
ans++;
}
}
}
return ans;
} int nums2(vector<int>& A, vector<int>& B, int la, int ra, int lb, int rb) {
int n = A.size();
int ans = 0;
int rightA1 = 0, sumA1 = 0, rightA2 = 0, sumA2 = 0, rightB1 = 0, sumB1 = 0, rightB2 = 0, sumB2 = 0;
for (int l = 0; l < n; l++) {
while (rightA1 < n && sumA1 + A[rightA1] < la) {
sumA1 += A[rightA1++];
}
while (rightA2 < n && sumA2 + A[rightA2] <= ra) {
sumA2 += A[rightA2++];
}
while (rightB1 < n && sumB1 + B[rightB1] < lb) {
sumB1 += B[rightB1++];
}
while (rightB2 < n && sumB2 + B[rightB2] <= rb) {
sumB2 += B[rightB2++];
}
int left = max(rightA1, rightB1);
int right = min(rightA2, rightB2);
if (left < right) {
ans += right - left;
}
if (rightA1 == l) {
rightA1++;
}
else {
sumA1 -= A[l];
}
sumA2 -= A[l];
if (rightB1 == l) {
rightB1++;
}
else {
sumB1 -= B[l];
}
sumB2 -= B[l];
}
return ans;
} vector<int> randomArray(int n, int v) {
vector<int> ans(n);
for (int i = 0; i < n; i++) {
ans[i] = rand() % v;
}
return ans;
} int main() {
int N = 50;
int V = 100;
int testTimes = 10000;
cout << "测试开始" << endl;
for (int i = 0; i < testTimes; i++) {
int n = rand() % N;
vector<int> A = randomArray(n, V);
vector<int> B = randomArray(n, V);
int a = rand() % V;
int b = rand() % V;
int c = rand() % V;
int d = rand() % V;
int la = min(a, b);
int ra = max(a, b);
int lb = min(c, d);
int rb = max(c, d);
int ans1 = nums1(A, B, la, ra, lb, rb);
int ans2 = nums2(A, B, la, ra, lb, rb);
if (ans1 != ans2) {
cout << "出错了!" << endl;
}
}
cout << "测试结束" << endl; return 0;
}

c完整代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <time.h> // 暴力方法
// 为了测试
int nums1(int* A, int* B, int n, int la, int ra, int lb, int rb) {
int ans = 0;
for (int l = 0; l < n; l++) {
for (int r = l; r < n; r++) {
int sumA = 0;
int sumB = 0;
for (int i = l; i <= r; i++) {
sumA += A[i];
sumB += B[i];
}
if (sumA >= la && sumA <= ra && sumB >= lb && sumB <= rb) {
ans++;
}
}
}
return ans;
} // 正式方法
// 时间复杂度O(N)
int nums2(int* A, int* B, int n, int la, int ra, int lb, int rb) {
int ans = 0;
int rightA1 = 0, sumA1 = 0, rightA2 = 0, sumA2 = 0, rightB1 = 0, sumB1 = 0, rightB2 = 0, sumB2 = 0;
for (int l = 0; l < n; l++) {
while (rightA1 < n && sumA1 + A[rightA1] < la) {
sumA1 += A[rightA1++];
}
while (rightA2 < n && sumA2 + A[rightA2] <= ra) {
sumA2 += A[rightA2++];
}
while (rightB1 < n && sumB1 + B[rightB1] < lb) {
sumB1 += B[rightB1++];
}
while (rightB2 < n&& sumB2 + B[rightB2] <= rb) {
sumB2 += B[rightB2++];
}
int left = rightA1 > rightB1 ? rightA1 : rightB1;
int right = rightA2 < rightB2 ? rightA2 : rightB2;
if (left < right) {
ans += right - left;
}
if (rightA1 == l) {
rightA1++;
}
else {
sumA1 -= A[l];
}
sumA2 -= A[l];
if (rightB1 == l) {
rightB1++;
}
else {
sumB1 -= B[l];
}
sumB2 -= B[l];
}
return ans;
} // 为了测试
int* randomArray(int n, int v) {
int* ans = (int*)malloc(sizeof(int) * n);
for (int i = 0; i < n; i++) {
ans[i] = rand() % v;
}
return ans;
} // 为了测试
int main() {
int N = 50;
int V = 100;
int testTimes = 10000;
printf("测试开始\n");
srand(time(NULL));
for (int i = 0; i < testTimes; i++) {
int n = rand() % N;
int* A = randomArray(n, V);
int* B = randomArray(n, V);
int a = rand() % V;
int b = rand() % V;
int c = rand() % V;
int d = rand() % V;
int la = (a < b) ? a : b;
int ra = (a > b) ? a : b;
int lb = (c < d) ? c : d;
int rb = (c > d) ? c : d;
int ans1 = nums1(A, B, n, la, ra, lb, rb);
int ans2 = nums2(A, B, n, la, ra, lb, rb);
if (ans1 != ans2) {
printf("出错了!\n");
}
free(A);
free(B);
}
printf("测试结束\n");
return 0;
}

2023-09-01:用go语言编写。给出两个长度均为n的数组, A = { a1, a2, ... ,an }, B = { b1, b2, ... ,bn }。 你需要求出其有多少个区间[L,R]的更多相关文章

  1. UPC 2224 Boring Counting (离线线段树,统计区间[l,r]之间大小在[A,B]中的数的个数)

    题目链接:http://acm.upc.edu.cn/problem.php?id=2224 题意:给出n个数pi,和m个查询,每个查询给出l,r,a,b,让你求在区间l~r之间的pi的个数(A< ...

  2. 主席树——求区间[l,r]不同数字个数的模板(向左密集 D-query)

    主席树的另一种用途,,(还有一种是求区间第k大,区间<=k的个数) 事实上:每个版本的主席树维护了每个值最后出现的位置 这种主席树不是以权值线段树为基础,而是以普通的线段树为下标的 /* 无修改 ...

  3. luogu P3834 【模板】可持久化线段树 1(主席树) 查询区间 [l, r] 内的第 k 小/大值

    ————————————————版权声明:本文为CSDN博主「ModestCoder_」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明.原文链接:https:// ...

  4. 查询数组里有多少个数在[L,R]范围中(二分)

    使用两次二分即可得到这个值 比如现在有一个vector<int> vec,里面存放的是有序数列. 我们现在希望找出范围在[L,R]之间的数有多少个. 则有cnt = upper_bound ...

  5. D. Powerful array 离线+莫队算法 给定n个数,m次查询;每次查询[l,r]的权值; 权值计算方法:区间某个数x的个数cnt,那么贡献为cnt*cnt*x; 所有贡献和即为该区间的值;

    D. Powerful array time limit per test seconds memory limit per test megabytes input standard input o ...

  6. hdu 4630 查询[L,R]区间内任意两个数的最大公约数

    No Pain No Game Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) ...

  7. HDU 6356 (线段树-l,r 之间小于val 的变val+单点求值)

    题目描述: 给你一个长度为n的最开始为0的数以及m个更新操作以及数据生成器参数X,Y,Z.每次操作,将由数据生成器生成出li,ri,vi.让你从区间[li,ri]中,将所有小于vi的数变为vi.最后让 ...

  8. 在一个由 'L' , 'R' 和 'X' 三个字符组成的字符串(例如"RXXLRXRXL")中进行移动操作。一次移动操作指用一个"LX"替换一个"XL",或者用一个"XR"替换一个"RX"。现给定起始字符串start和结束字符串end,请编写代码,当且仅当存在一系列移动操作使得start可以转换成end时, 返回True。

    在一个由 'L' , 'R' 和 'X' 三个字符组成的字符串(例如"RXXLRXRXL")中进行移动操作.一次移动操作指用一个"LX"替换一个"XL ...

  9. 2017-5-14 湘潭市赛 Partial Sum 给n个数,每次操作选择一个L,一个R,表示区间左右端点,该操作产生的贡献为[L+1,R]的和的绝对值-C。 0<=L<R<=n; 如果选过L,R这两个位置,那么以后选择的L,R都不可以再选择这两个位置。最多操作m次,求可以获得的 最大贡献和。

    Partial Sum Accepted : Submit : Time Limit : MS Memory Limit : KB Partial Sum Bobo has a integer seq ...

  10. Help Hanzo lightof 1197 求一段区间内素数个数,[l,r] 在 [1,1e9] 范围内。r-l<=1e5; 采用和平常筛素数的方法。平移区间即可。

    /** 题目:Help Hanzo lightof 1197 链接:https://vjudge.net/contest/154246#problem/M 题意:求一段区间内素数个数,[l,r] 在 ...

随机推荐

  1. phpstudy-sqlilabs-less-11

    题目:POST - Error Based - Single quotes- String 基于错误的单引号post型字符变形的注入 看到有个账密输入口第一反应尝试post注入 打开post data ...

  2. js 之二 事件对象

    事件对象 /当事件的响应函数被触发时,浏览器每次都会讲一个事件对象作为实参传递响应函数; 在事件对象中封装了当前事件相关的一切信息,比如:鼠标的,键盘的操作 // 当鼠标在areaDiv中移动时,在s ...

  3. 读文献先读图——主成分分析 PCA 图

    上周五彩斑斓的气泡图 有让你眼花缭乱吗? 本周,化繁为简的PCA图 你值得拥有!  数据分析| 科研制图﹒PCA 图 关键词:主成分分析.降维 1665 年的鼠疫 牛顿停课在家提出了万有引力 ;183 ...

  4. Linux 下的动态库、静态库与环境变量

    最近这几天在处理集群软件的过程中,遇到各种各样的库和环境变量的问题,被虐的不清!趁此机会,整理了一下 Linux 下静态库.动态库(共享库)和环境变量的一些知识,与大家共享一下. 库的种类 Linux ...

  5. JVM源码分析:深入剖析java.c文件中JavaMain方法中InitializeJVM的实现

    经过前文<从JDK源码级深入剖析main方法的运行机制>的分析,我们知道了实现JavaMain方法的四个主要步骤: 初始化Java虚拟机 加载主运行类 通过加载的主运行类,获取main方法 ...

  6. StencilJs学习之组件装饰器

    stenciljs 可以方便的构建交互式组件 支持以下装饰器 component state prop watch method element event listen Component 装饰器 ...

  7. RPA自动化如何帮助企业提高业务业务洞察力

    目录 1. 引言 2. 技术原理及概念 2.1 基本概念解释 2.2 技术原理介绍 2.3 相关技术比较 3. 实现步骤与流程 3.1 准备工作:环境配置与依赖安装 3.2 核心模块实现 3.3 集成 ...

  8. 讯飞离线语音合成新版(Aikit)-android sdk合成 demo(Java版本)

    前言:科大讯飞的新版离线语音合成,由于官网demo是kt语言开发的,咱也看不懂kt,搜遍了全网也没看到一个java版的新版离线语音demo,现记录下,留给有缘人参考!!!!!毕竟咱在这上面遇到了不少的 ...

  9. Lifecycle解决了什么问题,以及它的基本用法

    1.为何要引入Lifecycle? 我首先来举个大家都比较常见的例子:我们在android开发的时候,经常需要在页面的onCreate()方法中对组件进行初始化,在onPause()方法中停止组件,而 ...

  10. CF961E Tufurama题解

    我们维护一个存储下标数据的树状数组,先将 \(1\sim n\) 插入树状数组. 用 \(a\) 表示原数组,\(b\) 表示按照 \(a_i\) 排序后的数组. 我们从 \(1\) 开始统计,直到 ...