Tienes N números enteros, A 1 , A 2 , ..., A N . Debe lidiar con dos tipos de operaciones. Un tipo de operación es agregar un número dado a cada número en un intervalo dado. El otro es pedir la suma de números en un intervalo dado.
Entrada
La primera línea contiene dos números N y Q . 1 ≤ N , Q ≤ 100000.
La segunda línea contiene N números, los valores iniciales de A 1 , A 2 , ..., A N . -1000000000 ≤ A i ≤ 1000000000.
Cada una de las siguientes líneas Q representa una operación.
"C a b c " significa agregar c a cada uno de A a , A a +1 , ..., A b . -10000 ≤ c ≤ 10000.
"Q a b " significa consultar la suma de A a , A a +1 , ..., A b .
Salida
Debe responder todos los comandos Q en orden. Una respuesta en línea.
Entrada de muestra
5 10 1 2 3 4 5 6 7 8 9 10 Q 4 4 Q 1 10 Q 2 4 100 3 6 3 Q 2 4
Salida de muestra
4 55 9 15
Insinuación
// #include <bits / stdc ++. h> #include <stdio.h> usando el espacio de nombres std; typedef largo largo ll; const ll inf = 4e18 + 10 ; const int mod = 1000000007 ; const int mx = 5e6 + 5 ; // verifica los límites, ficticio // typedef pair <int, int> pa; // const double PI = acos (-1); // ll gcd (ll a, ll b) {return b? mcd (b, a% b): a; } // #define swa (a, b) a ^ = b ^ = a ^ = b // #define re (i, a, b) para (int i = (a), _ = (b); i < _; i ++) // #define rb (i, a, b) para (int i = (b), _ = (a); i> = _; i--) // #define clr (a) memset (a, 0, sizeof ( a)) // #define lowbit (x) ((x) & (x-1)) // #define mkp make_pair // void sc (int & x) {scanf ("% d", & x); } void sc (int64_t & x) {scanf ("% lld", & x); } void sc (doble & x) {scanf ("% lf", & x); } void sc (char & x) {scanf ("% c", & x); } void sc (char * x) {scanf ("% s", x); } ll suma [mx], suma [mx]; pushup nulo ( int rt) { sum [rt] = sum [rt << 1 ] + sum [rt << 1 | 1 ]; 更新 rt 的 子 节点 if (add [rt]) { add [rt << 1 ] + = add [rt]; agregar [rt << 1 | 1 ] + = agregar [rt]; suma [rt << 1 ] + = (m - (m >> 1 )) * agregar [rt]; suma [rt << 1 | 1 ] + = (m >> 1 ) * agregar [rt]; agregar [rt] = 0 ; // 取消 本 层 标记 } } #define lson l, mid, rt << 1 #define rson mid + 1, r, rt << 1 | 1 voidbiuld ( int l, int r, int rt) { // Construir un árbol con un árbol binario completo agregar [rt] = 0 ; if (l == r) { // nodo hoja, asignar scanf ( " % lld " , y sum [ rt]); return ; } int mid = (l + r) >> 1 ; biuld (lson); biuld (rson); pushup (rt); // intervalo de actualización hacia arriba y } actualización nula ( int a, int b, ll c, int l, int r,int rt) { // Actualización de intervalo if (a <= l && b> = r) { sum [rt] + = (r-l + 1 ) * c; add [rt] + = c; return ; } pushdown ( rt, r -l + 1 ); // Actualización hacia abajo int mid = (l + r) >> 1 ; if (a <= mid) update (a, b, c, lson); // Divide en dos mitades if (b> mid) update (a, b, c, rson); pushup (rt); } ll query ( int a, int b,int l, int r, int rt) { // 区间 求和 if (a <= l && b> = r) return sum [rt]; // 满足 perezoso 直接 返回 pushdown (rt, r - l + 1 ); int mid = (l + r) >> 1 ; ll ans = 0 ; if (a <= mid) ans + = query (a, b, lson); if (b> mid) ans + = query (a, b, rson); volver ans; } int main () { // ios :: sync_with_stdio (false); cin.tie (0); cout.tie (0); int n, m; scanf ( " % d " , & n); scanf ( " % d " , & m); biuld ( 1 , n, 1 ); while (m-- ) { char str [ 2 ]; int a, b; ll c; scanf ( " % s " , str); if (str [ 0 ] == ' C ' ) { scanf ( " % d " , & a); scanf ( ", & b); scanf ( " % lld " , & c); actualización (a, b, c, 1 , n, 1 ); } else { scanf ( " % d " , & a); scanf ( " % d " , & b); printf ( " % lld \ n " , consulta (a, b, 1 , n, 1 )); } } devuelve 0 ; }