Suma de prefijo previo (diferencia novedosa)

El problema

Dar una secuencia \ (a [i] \)

Prefijo y \ (S = \ sum \ limits_ {i = 1} ^ {n} a [i] \)

Pre-prefijo y \ (SS = \ sum \ limits_ {i = 1} ^ {n} S [i] \)

Ahora da \ (n \) operaciones. Algunos son para modificar un determinado \ (a [i] \) , algunos para consultar un determinado \ (SS [i] \)

Línea divisoria manual

\ (S [i] = a [1] + a [2] + ... + a [i] \)

\ (SS [i] = S [1] + S [2] + ... + S [i] \)

Cuando un modificado \ (a [i] \) a (X \) \ Cuando, por \ (S \) intervalo de tiempo es equivalente a \ ([i, n] \ ) están más el \ (xa [i] \ )

Para \ (SS \) , es equivalente a agregar \ (k (xa [i]) \) al intervalo \ ([i, n] \) , donde \ (k \) es una constante, con \ ( i \) aumenta

\ (Entonces las anteriores no tienen sentido, esta pregunta no tiene nada que ver con la secuencia S y la diferencia (manual divertido) \)

De hecho, cada vez que consulta \ (SS [i] \) , la respuesta es el original \ (SS [i] \) más la suma de intervalos de las operaciones realizadas durante el intervalo \ ([1, i] \) .

De hecho, mantenemos una nueva secuencia \ (temp \) , cada vez que modifica \ (a [i] \), puede modificar directamente el árbol de líneas en él.

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=100009;
ll n,m;
ll e[maxn],s[maxn],sumn[maxn];
ll ss[maxn],ssumn[maxn],ans[maxn];
struct p{
	ll l,r,w,lazy;
}a[maxn*4];
void build(ll p,ll l,ll r){
	a[p].l=l,a[p].r=r;
	if(l==r){
		a[p].w=0;
		return;
	}
	ll mid=l+r>>1;
	build(p<<1,l,mid);
	build(p<<1|1,mid+1,r);
	a[p].w=a[p<<1].w+a[p<<1|1].w;
}
void pushdown(int p){
	a[p<<1].lazy+=a[p].lazy;
	a[p<<1|1].lazy+=a[p].lazy;
	a[p<<1].w+=a[p].lazy*(a[p<<1].r-a[p<<1].l+1);
	a[p<<1|1].w+=a[p].lazy*(a[p<<1|1].r-a[p<<1|1].l+1);
	a[p].lazy=0;
}
void add(ll p,ll l,ll r,ll k){
	if(a[p].l>=l&&a[p].r<=r){
		a[p].lazy+=k;
		a[p].w+=k*(a[p].r-a[p].l+1);
		return;
	}
	pushdown(p);
	int mid=a[p].l+a[p].r>>1;
	if(mid>=l)	add(p<<1,l,r,k);
	if(mid<r)	add(p<<1|1,l,r,k);
	a[p].w=a[p<<1].w+a[p<<1|1].w;		
}
ll ssss=0;
void ask(ll p,ll l,ll r)
{
	if(a[p].l>=l&&a[p].r<=r){
		ssss+=a[p].w;
		return;
	}
	pushdown(p);
	ll mid=a[p].l+a[p].r>>1;
	if(mid>=l)	ask(p<<1,l,r);
	if(mid<r)	ask(p<<1|1,l,r);
}
int main()
{
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	{
		scanf("%lld",&e[i]);
		sumn[i]=e[i]+sumn[i-1];//i到n都修改k
		ssumn[i]=ssumn[i-1]+sumn[i];//i到n都修改(n-i)k 
	}
	build(1,1,n);
	for(int i=1;i<=m;i++)
	{
		string s;
		cin>>s;
		if(s[0]=='Q')
		{
			ssss=0;
			ll l;
			scanf("%lld",&l);
			ask(1,1,l);
			printf("%lld\n",ssss+ssumn[l]);
		}
		else
		{
			ll l,r;
			scanf("%lld%lld",&l,&r);
			ll k=r-e[l];
			add(1,l,n,k);
			e[l]=r;
		}
	}	
}

Supongo que te gusta

Origin www.cnblogs.com/iss-ue/p/12672959.html
Recomendado
Clasificación