using
System;
using
System.Collections.Generic;
class
GFG {
static
int
MAX = 100001;
static
int
SQRSIZE = 400;
static
int
query_blk_sz;
static
int
[] frequency =
new
int
[MAX];
static
int
[] blocks =
new
int
[SQRSIZE];
static
int
blk_sz;
public
class
Query {
public
int
L;
public
int
R;
public
int
x;
public
Query(
int
a,
int
b,
int
c)
{
L = a;
R = b;
x = c;
}
}
static
int
getblocknumber(
int
ind)
{
return
ind / blk_sz;
}
static
int
getans(
int
k)
{
int
ans = 0;
int
left_blk, right_blk;
left_blk = 0;
right_blk = getblocknumber(k);
if
(left_blk == right_blk) {
for
(
int
i = 0; i <= k; i++) {
ans += frequency[i];
}
}
else
{
for
(
int
i = 0; i < (left_blk + 1) * blk_sz;
i++) {
ans += frequency[i];
}
for
(
int
i = left_blk + 1; i < right_blk; i++) {
ans += blocks[i];
}
for
(
int
i = right_blk * blk_sz; i <= k; i++) {
ans += frequency[i];
}
}
return
ans;
}
static
void
add(
int
ind,
int
[] a)
{
frequency[a[ind]]++;
int
block_num = getblocknumber(a[ind]);
blocks[block_num]++;
}
static
void
remove(
int
ind,
int
[] a)
{
frequency[a[ind]]--;
int
block_num = getblocknumber(a[ind]);
blocks[block_num]--;
}
static
void
queryResults(
int
[] a,
int
n, Query[] q,
int
m)
{
query_blk_sz = (
int
)Math.Sqrt(m);
Array.Sort(q,
new
Comparison<Query>((x, y) => {
if
(x.L / query_blk_sz
!= y.L / query_blk_sz) {
return
x.L / query_blk_sz
- y.L / query_blk_sz;
}
return
x.R - y.R;
}));
int
currL = 0, currR = 0;
for
(
int
i = 0; i < m; i++) {
int
L = q[i].L, R = q[i].R, x = q[i].x;
while
(currR <= R) {
add(currR, a);
currR++;
}
while
(currL > L) {
add(currL - 1, a);
currL--;
}
while
(currR > R + 1) {
remove(currR - 1, a);
currR--;
}
while
(currL < L) {
remove(currL, a);
currL++;
}
Console.WriteLine(
"query["
+ L +
", "
+ R +
", "
+ x +
"] : "
+ getans(x));
}
}
static
void
Main(
string
[] args)
{
int
[] arr = { 2, 0, 3, 1, 4, 2, 5, 11 };
int
n = arr.Length;
blk_sz = (
int
)Math.Sqrt(n);
Query[] q
= {
new
Query(0, 2, 2),
new
Query(0, 3, 5),
new
Query(5, 7, 10) };
int
m = q.Length;
queryResults(arr, n, q, m);
}
}