RT,蒟蒻分块求助。
题面:点我
#include <string.h>
#include <stdio.h>
typedef long long LL;
inline long long read()
{
long long num = 0; int f = 1; char c = getchar();
while (c < 48 || c>57){ if (c == '-')f = -1; c = getchar(); }
while (c >= 48 && c <= 57)num = (num << 3) + (num << 1) + (c ^ 48), c = getchar();
return num*f;
}
LL a[50305], BLOCK[230], brl[50005], sum[230];
int BLOCKSIZE = 224;
#include <math.h>
//224 one block
#include <algorithm>
inline LL min(LL a, LL b)
{
return a < b ? a : b;
}
signed main()
{
LL n = read();
//BLOCKSIZE = sqrt(n);
for (LL i = 1; i <= n; i++)a[i] = read(), brl[i] = (i - 1) / BLOCKSIZE + 1, sum[brl[i]] += a[i];
{
LL LB = 1, RB = brl[n];
std::sort(a + 1, a + min(BLOCKSIZE*LB, n) + 1);
if (LB != RB)
{
for (LL i = LB + 1; i < RB; i++)
{
std::sort(a + 1 + (i - 1)*BLOCKSIZE, a + 1 + i*BLOCKSIZE);
}
int f = 0;
if ((RB - 1)*BLOCKSIZE + 1 <= n)
std::sort(a + (RB - 1)*BLOCKSIZE + 1, a + n + 1);
}
}
for (LL ii = 0; ii < n; ii++)
{
LL opt = read(), l = read(), r = read(), c = read();
if (opt)
{
LL LB = brl[l], RB = brl[r];
LL ans = 0;
for (LL i = l; i <= min(BLOCKSIZE*LB, r); i++)if (a[i] + BLOCK[LB] < c*c) ans++;
if (LB != RB)
{
for (LL i = LB + 1; i < RB; i++)
ans += (std::lower_bound(a + 1 + (i - 1)*BLOCKSIZE, a + 1 + i*BLOCKSIZE, c*c - BLOCK[i]) - a - (i - 1)*BLOCKSIZE - 1);
for (LL i = (RB - 1)*BLOCKSIZE + 1; i <= r; i++)if(a[i] + BLOCK[RB] < c*c)ans++;
}
printf("%lld\n", ans);
}
else
{
LL LB = brl[l], RB = brl[r];
for (LL i = l; i <= min(BLOCKSIZE*LB, r); i++)a[i] += c;
std::sort(a + l, a + min(BLOCKSIZE*LB, r) + 1);
if (LB != RB)
{
for (LL i = LB + 1; i < RB; i++)BLOCK[i] += c;
int f = 0;
for (LL i = (RB - 1)*BLOCKSIZE + 1; i <= r; i++)a[i] += c, f = 1;
if (f)
std::sort(a + (RB - 1)*BLOCKSIZE + 1, a + r + 1);
}
}
}///w///hile (1);
getchar();
return 0;
}
样例能过,提交全WA