Pagini recente » Heist | Diferente pentru documentatie/borderoul-de-evaluare intre reviziile 15 si 10 | Camp | Climbers | Cod sursa (job #9506)
Cod sursa(job #9506)
#include <cstdio>
using namespace std;
const char iname[] = "secv5.in";
const char oname[] = "secv5.out";
#define MAX_N 1050000
#define MAX_BUF 11000000
typedef unsigned int u32;
int N, L, U;
u32 X[MAX_N];
u32 A[MAX_N];
u32 H[MAX_N];
int cntL[MAX_N], cntU[MAX_N], size;
int log;
char buffer[MAX_BUF];
void down(u32 H[], u32 z)
{
u32 l, r, k;
for (int done = 0; !done; ) {
done = 0;
l = z * 2;
r = z * 2 + 1;
k = z;
if ((l <= H[0]) && (H[l] < H[k]))
k = l;
if ((r <= H[0]) && (H[r] < H[k]))
k = r;
if (k != z)
H[k] ^= H[z] ^= H[k] ^= H[z], z = k;
else
done = 1;
}
}
void insert(u32 H[], const u32 num)
{
u32 k;
for (k = (++ H[0]); (k > 1) && (H[k >> 1] > num); k >>= 1)
H[k] = H[k >> 1];
H[k] = num;
}
u32 getmin(u32 H[])
{
u32 num = H[1];
H[1] = H[H[0] --];
if (H[0] > 1)
down(H, 1);
return num;
}
void read_in(void)
{
freopen(iname, "r", stdin);
scanf("%d %d %d\n", &N, &L, &U);
int len = int(fread(buffer, sizeof(char), MAX_BUF, stdin));
char *p = buffer;
char *lim = buffer + len;
for (int i = 0; i < N; ++i) {
u32 num = 0;
for (; (p < lim) && (*p) < '0'; ++p) ;
for (; (p < lim) && (*p) >= '0'; ++p)
num = num * 10 + (u32)((*p) - '0');
X[i] = num;
insert(H, num);
}
for (int i = 0; H[0] > 0; ) {
A[i] = getmin(H);
if ((i == 0) || (A[i - 1] != A[i]))
i ++;
}
size = i;
}
int search(const u32 num)
{
int k;
int stp = log;
for (k = 0; stp; stp >>= 1) {
if ((k + stp < size) && (A[k + stp] <= num))
k += stp;
}
return k;
}
int main(void)
{
read_in();
for (log = 1; log < size; log <<= 1) ;
int i;
int k;
int FL, numL = 0;
int FU, numU = 0;
long long Res = 0;
for (i = FU = FL = 0; i < N; ++i) {
k = search(X[i]);
cntL[k] ++;
if (cntL[k] == 1)
numL ++;
cntU[k] ++;
if (cntU[k] == 1)
numU ++;
for (; numU > U; ++FU) {
k = search(X[FU]);
cntU[k] --;
if (cntU[k] == 0)
numU --;
}
for (; numL >= L; ++FL) {
k = search(X[FL]);
if ((cntL[k] == 1) && (numL == L))
break ;
cntL[k] --;
if (cntL[k] == 0)
numL --;
}
if (L == numL)
Res += (long long)(FL - FU + 1);
}
freopen(oname, "w", stdout);
printf("%lld\n", Res);
return 0;
}