Bloquear
El bloqueo se considera una violencia elegante, principalmente por la cuestión del intervalo.
Bloquear significa dividir un segmento en muchos bloques,
Usualmente usamos x = sqrt (n) para representar el tamaño de un bloque
num = ceil (n × \ veces× 1.0 / x) para indicar el número de bloques
El requisito principal para la fragmentación son 3 matrices,
pos [i] es para indicar el bloque donde se encuentra el i-ésimo número
l [i] representa el punto final izquierdo del i-ésimo bloque
r [i] representa el punto final derecho del i-ésimo bloque
Por ejemplo, la siguiente pregunta
Tenemos que crear otra matriz ans [i] para representar el número que agregamos al bloque i-ésimo.
Pero esto da lugar a una pregunta, si el bloque i-ésimo incluido en el intervalo agregado está incompleto, ¿podemos agregar c on ans [i],
La respuesta es no.
Para bloques incompletos, deberíamos resolverlos violentamente agregando c a la matriz a, es decir, la matriz original
Para el bloque completo, solo necesitamos agregar c a la matriz ans.
Entonces, el resultado final es que el tamaño del número i-ésimo es un [i] + ans [pos [i]]
Descripción del Título
Dada una secuencia de operaciones de longitud n y n, las operaciones implican la suma de intervalos y la búsqueda de un solo punto.
Formato de entrada
Ingrese un número en la primera línea. Ingrese n números en la segunda línea y el i- ésimo número es una [i] , separados por espacios.
Luego, ingrese n líneas de consulta e ingrese cuatro dígitos opt, l, r, c en cada línea separados por espacios,
Si opt = 0 significa sumar c a todos los números entre [l, r].
Si opt = 1 , significa pedir el valor de a [r]
Formato de salida
Para cada consulta, genere un número en una línea para indicar la respuesta.
Muestra
Entrada de muestra
4
1 2 2 3
0 1 3 1
1 0 1 0
0 1 2 2
1 0 2 0
Salida de muestra
2
5
#include<bits/stdc++.h>
using namespace std;
int l[2005],r[2005] ,pos[50005],a[50005],ans[50005];
void add(int ll,int rr,int v)
{
int posl=pos[ll];
int posr=pos[rr];
if(posr-posl<=1)/*这个表示要加的区间在一个块内,即直接在原数组a上加*/
{
for(int i=ll;i<=rr;i++)
{
a[i]=a[i]+v;
}
}
else
{
for(int i=ll;i<=r[posl];i++)/*前面的不完整的块*/
a[i]=a[i]+v;
for(int i=pos[ll]+1;i<pos[rr];i++)/*完整的块*/
ans[i]+=v;
for(int i=l[posr];i<=rr;i++)/*后面不完整的块*/
a[i]=a[i]+v;
}
}
void shuchu(int rr)
{
if(ans[pos[rr]])
printf("%d\n",a[rr]+ans[pos[rr]]);
else
printf("%d\n",a[rr]);
}
int main()
{
int n;
int opt ,ll,rr,cc;
cin>>n;
int x=sqrt(n);
int num=ceil(n*1.0/x);
for(int i=1;i<=num;i++)/*预处理l和r 数组*/
{
l[i]=(i-1)*x+1;
r[i]=i*x;
}
r[num]=n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
pos[i]=(i-1)/x+1; /*处理pos数组*/
}
for(int i=1;i<=n;i++)
{
cin>>opt>>ll>>rr>>cc;
if(opt==0)
{
add(ll,rr,cc);
}
else
{
shuchu(rr);
}
}
return 0;
}