문
portal1을 : Luogu
기술
묘지의 관리인은 그 사람들이 묘지 낙관 할 수 있습니다 자신의 무덤 골키퍼에 정착 자신의 무덤 조상의 편안한 느낌, 그래서 전에 도난당한 적이없는 황량한 묘지 무덤 골키퍼의 유서 깊은 있습니다 그것은 피할 수보다는 우연 .....
무덤 골키퍼 때문에 .... 풍수를 이해합니다. 그는 묘지가, 메이저와 마이너 삭제 표시 삭제 표시에 주로 묘비 만 나누어 져 있습니다 \ (1 \) 개월, 그와 같은 언급 된 무덤 골키퍼 \ (1 \) , 수를하는 동안 보조 삭제 표시 \ (N-1 \) 한 수의 중대한 키퍼 (상기 n DOTS \ \ 2, 3) \ 하는 구성 (n \) \ 묘지 묘비.
그리고 각각의 묘비가 풍수의 초기 값을 가지며,이 값은 좋은 또는 나쁜 풍수 풍수 묘지를 결정, 무덤 골키퍼가 종종 이러한 삭제 표시를 조회 할 필요가있다.
그들은 무한한 생명을 소유하도록 보호대, 또 다시 변경하여 풍수, 무덤 골키퍼의 좋은 사용은, 아무도 그가 산 시간을 모른다.
그 날, 당신은 그를 방문 할 운, 그는 당신을 묻는 그는 그의 승리의 다음 몇 년을 목격하지만, 그 때마다하지만 풍수 값을 계산하고 그가 당신을 원할 것입니다 잘못 계산 그가 계산하기 위해 당신을 필요로 생활 QAQ
특별한 사정이 다음에 알려졌다하지 않는 한, 풍수,하지 불변 (\ 2,147,483,647 \) 년,이됩니다 \ (n \) 재해의 시간, 무덤 골키퍼가 여러 가지 작업을해야합니다 :
\는 ([L은 R이] \ ) 이 간격의 모든 값 풍수 삭제 증가 \ (K \) ;
풍수 마스터는 삭제 표시의 값이 증가합니다 \ (케이 \)를 ;
주요의 풍수 묘비 감소 된 가치 \ (K \) ;
통계 \ ([L, R] \ ) 이 간격의 모든 모비 풍수 값;
주님은 풍수 값을 삭제 표시합니다.
위에서 말했다, 많은 사람들이 여기에 집에서 조상, 그리고 여러 세기 무덤 골키퍼가 살았던의 무덤, 묘비의 수는 당신의 더 믿을 수있을 것입니다 것, 무덤 골키퍼가 친절하게 그에게 이러한 작업을 완료 할 수 있도록 여러분을 초대, 그렇지 않으면 폭발의 날 호텔, 칼 아래 하늘 \ (\ 도트 \ 점 \) 위해 살아 남기 위해, 또는 그를 도와있다.
입력
첫 번째 줄은, 두 개의 양의 정수가 \ (N, F \)가 총 대표 \ (n \) 삭제 표시를하고, 다음에 \ (2147483647 \) 년,이됩니다 \ (F \) 배 세계의 끝;
두번째 라인 \ N- (\) 의 양의 정수는 대표 \ (나는 \) 모비 풍수 값;
다음 \ (f를 \)의 각각은 타이틀, 동일 타이틀 태그로서 세계의 끝 대한 해결책을 갖고 로우.
산출
출력의 여러 행이 될 것입니다 \ (4 \) 와 \ (5 \) 대답 할 질문입니다.
샘플 입력
5 7
0 0 0 0 0
1 1 5 1
1 1 3 3
2 3
3 1
4 1 5
2 1
5
샘플 출력
16
7
힌트
\ (20 \ %의 \) 데이터 만족 : \ (1 \ n 르 \ 르 100 \.) ;
\ (50 \ %의 \) 데이터 만족 : \ (1 \ n 르 \ 르 6000 \.) ;
(\ 100 \ %의 \) 데이터를 만족 : \ (1 \ n 르, F \ 2 르 \ 시간 10 ^ {5} \.) ;
해결책
이 문제 펜윅 나무.
사용 c1[]
, 유지하고 c2[]
플롯을 유지하기 위해.
조회 \는 ([X는 Y가] \ ) 의 간격이 수 query(y) - query(x - 1) + (x == 1) * 主墓碑的风水值
있는 평가 query(y) - query(x - 1)
접두사 비슷하고 (x == 1) * 主墓碑的风水值
나타내는 \가 ([x가, y는] \ ) 메인 단일 삭제를 포함하는 결합한다면 간격, 기본 패키지 묘비를 포함하지 않는다 유지 보수.
상기 주요 묘비는 별도의 유지 관리 할 필요가있다.
암호
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long LL;
const int MAXN = 500005;
int n, m, last;
LL first_value, c1[MAXN], c2[MAXN];
inline int lowbit(int x) {//树状数组专属操作
return x & -x;
}
inline void update(int x, LL val) {//更新
for (LL i = x; i <= n; i += lowbit(i)) {
c1[i] += val;
c2[i] += val * x;
}
}
inline LL query(int x) {//查询
LL ret = 0;
for (LL i = x; i; i -= lowbit(i))
ret += (x + 1) * c1[i] - c2[i];
return ret;
}
int main() {
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; i++) {
int x;
scanf("%d", &x);
update(i, x - last);
last = x;
}
while (m--) {
int opt, x, y;
LL val;
scanf("%d", &opt);
if (opt == 1) {
scanf("%d%d%lld", &x, &y, &val);
update(x, val);
update(y + 1, -val);
} else
if (opt == 2) {
scanf("%lld", &val);
first_value += val;
} else
if (opt == 3) {
scanf("%lld", &val);
first_value -= val;
} else
if (opt == 4) {
scanf("%d%d", &x, &y);
printf("%lld\n", query(y) - query(x - 1) + (x == 1) * first_value);
} else printf("%lld\n", query(1) + first_value);//统一维护的加单独维护的
}
return 0;
}