Time Limit: 20 Sec Memory Limit: 128 MB
Submit: 1734 Solved: 684
[Submit][Status][Discuss]

## Description

Y901高速公路是一条重要的交通纽带，政府部门建设初期的投入以及使用期间的养护费用都不低，因此政府在这条高速公路上设立了许多收费站。
Y901高速公路是一条由N-1段路以及N个收费站组成的东西向的链，我们按照由西向东的顺序将收费站依次编号为1~N，从收费站i行驶到i+1(或从i+1行驶到i)需要收取Vi的费用。高速路刚建成时所有的路段都是免费的。

# Input

C l r v 表示将第l个收费站到第r个收费站之间的所有道路的通行费全部增加v
Q l r 表示对于给定的l,r，要求回答小A的问题

4 5

C 1 4 2

C 1 2 -1

Q 1 2

Q 2 4

Q 1 4

1/1

8/3

17/6

## HINT

Test N M

1 =10 =10

2 =100 =100

3 =1000 =1000

4 =10000 =10000

5 =50000 =50000

6 =60000 =60000

7 =70000 =70000

8 =80000 =80000

9 =90000 =90000

10 =100000 =100000

# 题解

$Sum = \sum_{i=l}^r (i - l + 1) \times (r - i + 1)$

$=(r - l - lr + 1) \sum_{i=l}^rv_i + (x + y)\sum_{i=l}^rv_ii-\sum_{i=l}^rv_ii^2$

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <map>
#include <cmath>
inline long long max(long long a, long long b){return a > b ? a : b;}
inline long long min(long long a, long long b){return a < b ? a : b;}
inline void swap(long long &x, long long &y){long long tmp = x;x = y;y = tmp;}
{
x = 0;char ch = getchar(), c = ch;
while(ch < '0' || ch > '9') c = ch, ch = getchar();
while(ch <= '9' && ch >= '0') x = x * 10 + ch - '0', ch = getchar();
if(c == '-') x = -x;
}
const long long INF = 0x3f3f3f3f3f3f3f3f;
const long long MAXN = 100000 + 10;
struct Node
{
long long sum_i, sum_i2, sum_v, sum_vi, sum_vi2, len;
Node(){sum_i = sum_i2 = sum_v = sum_vi = sum_vi2 = len = add = 0;}
}node[MAXN << 2];
Node merge(Node& a, Node& b)
{
Node re;
re.sum_v = a.sum_v + b.sum_v;
re.sum_vi = a.sum_vi + b.sum_vi;
re.sum_vi2 = a.sum_vi2 + b.sum_vi2;
return re;
}
void pushup(long long o)
{
Node& re = node[o], &a = node[o << 1], &b = node[o << 1 | 1];
re.sum_v = a.sum_v + b.sum_v;
re.sum_vi = a.sum_vi + b.sum_vi;
re.sum_vi2 = a.sum_vi2 + b.sum_vi2;
}
void pushdown(long long o)
{
{
for(long long i = 0;i <= 1;++ i)
{
Node &a = node[o << 1 | i];
a.sum_v += a.len * v;
a.sum_vi += a.sum_i * v;
a.sum_vi2 += a.sum_i2 * v;
}
}
}
long long n, q;
void build(long long o = 1, long long l = 1, long long r = n)
{
if(l == r)
{
node[o].sum_i = l, node[o].sum_i2 = l * l, node[o].len = 1;
return;
}
long long mid = (l + r) >> 1;
build(o << 1, l, mid);
build(o << 1 | 1, mid + 1, r);
node[o].len = node[o << 1].len + node[o << 1 | 1].len;
node[o].sum_i = node[o << 1].sum_i + node[o << 1 | 1].sum_i;
node[o].sum_i2 = node[o << 1].sum_i2 + node[o << 1 | 1].sum_i2;
}
void modify(long long ll, long long rr, long long k, long long o = 1, long long l = 1, long long r = n)
{
if(l != r) pushdown(o);
if(ll <= l && rr >= r)
{
node[o].sum_v += k * node[o].len;
node[o].sum_vi += k * node[o].sum_i;
node[o].sum_vi2 += k * node[o].sum_i2;
return;
}
long long mid = (l + r) >> 1;
if(mid >= ll) modify(ll, rr, k, o << 1, l, mid);
if(mid < rr) modify(ll, rr, k, o << 1 | 1, mid + 1, r);
pushup(o);
}
Node ask(long long ll, long long rr, long long o = 1, long long l = 1, long long r = n)
{
if(l != r) pushdown(o);
if(ll <= l && rr >= r) return node[o];
Node a, b, re;
long long mid = (l + r) >> 1;
if(mid >= ll) a = ask(ll, rr, o << 1, l, mid);
if(mid < rr) b = ask(ll, rr, o << 1 | 1, mid + 1, r);
pushup(o);
re = merge(a, b);
return re;
}
char s[10];
long long gcd(long long a, long long b)
{
return !b ? a : gcd(b, a%b);
}
int main()
{
build();
for(long long i = 1;i <= q;++ i)
{
scanf("%s", s + 1);