给定[]含有第一N的自然数的排列的整数中号≤为N的阵列ARR。任务是找到子阵列的数量,以使序列的中位数为M。
序列的中位数是元素的值,该元素在以非降序排序后位于序列的中间。如果序列的长度是偶数,则使用两个中间元素的左侧。
例子:
Input: a[] = { 2, 4, 5, 3, 1}, M = 4
Output: 4
Required sub-arrays are {2, 4, 5}, {4}, {4, 5} and {4, 5, 3}.
Input: a[] = { 1, 2, 3, 4, 5}, M = 5
Output: 1
方法:当且仅当M属于段p [l..r]时,中位数等于M,并且less =大于或小于=较大– 1,其中p [l..r]中元素的数量较少严格小于M和更大是p中是严格大于M.在这里,我们使用了一个事实,即p是一个置换(上p元素[l..r]的数目[l..r]正好有一个出现M)。
换句话说,M属于p [l..r],且值大–小等于0或1。
计算前缀求和sum [0..n],其中sum [i]在长度i的前缀上(即在子数组p [0..i-1]上) -小于或等于更大的值。对于固定值r,很容易计算出p [l..r]合适的l的数量。首先,检查M是否在[0..r]上相遇。有效值l是这样的索引:[0..l-1]上没有M,并且sum [l] = sum [r]或sum [r] = sum [l] +1。
让我们为每个值在M的左边保留一些前缀和sum [i]。我们可以只使用一个映射c,其中c [s]是多个这样的索引l,sum [l] = s和l在m的左边。
因此,对于每个p [0..r]包含m的r,做ans + = c [sum] + c [sum – 1],其中sum是当前值Greater -less 。
下面是上述方法的实现:
C++
// C++ implementation of the approach
#include
using namespace std;
// Function to return the count of sub-arrays
// in the given permutation of first n natural
// numbers such that their median is m
int segments(int n, int p[], int m)
{
map c;
c[0] = 1;
bool has = false;
int sum = 0;
long long ans = 0;
for (int r = 0; r < n; r++) {
// If element is less than m
if (p[r] < m)
sum--;
// If element greater than m
else if (p[r] > m)
sum++;
// If m is found
if (p[r] == m)
has = true;
// Count the answer
if (has)
ans += c[sum] + c[sum - 1];
// Increment sum
else
c[sum]++;
}
return ans;
}
// Driver code
int main()
{
int a[] = { 2, 4, 5, 3, 1 };
int n = sizeof(a) / sizeof(a[0]);
int m = 4;
cout << segments(n, a, m);
return 0;
}
Java
// Java implementation of the approach
import java.util.HashMap;
class GFG
{
// Function to return the count of sub-arrays
// in the given permutation of first n natural
// numbers such that their median is m
public static int segments(int n, int[] p, int m)
{
HashMap c = new HashMap<>();
c.put(0, 1);
boolean has = false;
int sum = 0;
int ans = 0;
for (int r = 0; r < n; r++)
{
// If element is less than m
if (p[r] < m)
sum--;
// If element greater than m
else if (p[r] > m)
sum++;
// If m is found
if (p[r] == m)
has = true;
// Count the answer
if (has)
ans += (c.get(sum) == null ? 0 :
c.get(sum)) +
(c.get(sum - 1) == null ? 0 :
c.get(sum - 1));
// Increment sum
else
c.put(sum, c.get(sum) == null ? 1 :
c.get(sum) + 1);
}
return ans;
}
// Driver code
public static void main(String[] args)
{
int[] a = { 2, 4, 5, 3, 1 };
int n = a.length;
int m = 4;
System.out.println(segments(n, a, m));
}
}
// This code is contributed by
// sanjeev2552
Python3
# Python3 implementation of the approach
# Function to return the count of sub-arrays
# in the given permutation of first n natural
# numbers such that their median is m
def segments(n, p, m):
c = dict()
c[0] = 1
has = False
Sum = 0
ans = 0
for r in range(n):
# If element is less than m
if (p[r] < m):
Sum -= 1
# If element greater than m
elif (p[r] > m):
Sum += 1
# If m is found
if (p[r] == m):
has = True
# Count the answer
if (has):
if(Sum in c.keys()):
ans += c[Sum]
if Sum-1 in c.keys():
ans += c[Sum - 1]
# Increment Sum
else:
c[Sum] = c.get(Sum, 0) + 1
return ans
# Driver code
a = [2, 4, 5, 3, 1]
n = len(a)
m = 4
print(segments(n, a, m))
# This code is contributed by mohit kumar
C#
// C# implementation of the approach
using System;
using System.Collections.Generic;
class GFG
{
// Function to return the count of sub-arrays
// in the given permutation of first n natural
// numbers such that their median is m
public static int segments(int n, int[] p, int m)
{
Dictionary c = new Dictionary();
c.Add(0, 1);
bool has = false;
int sum = 0;
int ans = 0;
for (int r = 0; r < n; r++)
{
// If element is less than m
if (p[r] < m)
sum--;
// If element greater than m
else if (p[r] > m)
sum++;
// If m is found
if (p[r] == m)
has = true;
// Count the answer
if (has)
ans += (!c.ContainsKey(sum) ? 0 :
c[sum]) +
(!c.ContainsKey(sum - 1) ? 0 :
c[sum - 1]);
// Increment sum
else
c.Add(sum, !c.ContainsKey(sum) ? 1 :
c[sum] + 1);
}
return ans;
}
// Driver code
public static void Main(String[] args)
{
int[] a = { 2, 4, 5, 3, 1 };
int n = a.Length;
int m = 4;
Console.WriteLine(segments(n, a, m));
}
}
// This code is contributed by 29AjayKumar
PHP
$m)
$sum++;
// If m is found
if ($p[$r] == $m)
$has = true;
// Count the answer
if ($has)
$ans += $c[$sum] + $c[$sum - 1];
// Increment sum
else
$c[$sum]++;
}
return $ans;
}
// Driver code
$a = array( 2, 4, 5, 3, 1 );
$n = count($a);
$m = 4;
echo segments($n, $a, $m);
// This code is contributed by Ryuga
?>
4