using
System;
using
System.Collections.Generic;
public
class
GFG {
static
int
block;
static
void
add(
int
x,
int
[] currentAns,
Dictionary<
int
,
int
> freq)
{
freq.TryGetValue(x,
out
int
value);
freq[x] = value + 1;
if
(freq[x] == x + 1) {
currentAns[0]--;
}
else
if
(freq[x] == x) {
currentAns[0]++;
}
}
static
void
remove(
int
x,
int
[] currentAns,
Dictionary<
int
,
int
> freq)
{
freq[x]--;
if
(freq[x] == x) {
currentAns[0]++;
}
else
if
(freq[x] == x - 1) {
currentAns[0]--;
}
}
class
Query {
public
int
L;
public
int
R;
public
int
index;
public
Query(
int
L,
int
R,
int
index)
{
this
.L = L;
this
.R = R;
this
.index = index;
}
}
static
void
queryResultsUtil(
int
[] a, Query[] q,
int
[] ans,
int
m)
{
var
freq =
new
Dictionary<
int
,
int
>();
int
currL = 0, currR = 0;
int
[] currentAns = { 0 };
for
(
int
i = 0; i < m; i++) {
int
L = q[i].L, R = q[i].R;
int
index = q[i].index;
while
(currL < L) {
remove(a[currL], currentAns, freq);
currL++;
}
while
(currL > L) {
currL--;
add(a[currL], currentAns, freq);
}
while
(currR <= R) {
add(a[currR], currentAns, freq);
currR++;
}
while
(currR > R + 1) {
currR--;
remove(a[currR], currentAns, freq);
}
ans[index] = currentAns[0];
}
}
static
void
queryResults(
int
[] a,
int
n, Query[] q,
int
m)
{
block = (
int
)Math.Sqrt(n);
Array.Sort(q, (x, y) => {
if
(x.L / block != y.L / block) {
return
x.L / block - y.L / block;
}
return
x.R - y.R;
});
int
[] ans =
new
int
[m];
queryResultsUtil(a, q, ans, m);
for
(
int
i = 0; i < m; i++) {
Console.WriteLine(
"Answer for Query "
+ (i + 1)
+
" = "
+ ans[i]);
}
}
public
static
void
Main(
string
[] args)
{
int
[] A = { 1, 2, 2, 3, 3, 3 };
int
n = A.Length;
Query[] q
= {
new
Query(0, 1, 0),
new
Query(1, 1, 1),
new
Query(0, 2, 2),
new
Query(1, 3, 3),
new
Query(3, 5, 4),
new
Query(0, 5, 5) };
int
m = q.Length;
queryResults(A, n, q, m);
}
}