[BZOJ1798][Ahoi2009]Seq 维护序列seq

[BZOJ1798][Ahoi2009]Seq 维护序列seq

7 43
1 2 3 4 5 6 7
5
1 2 5 5
3 2 4
2 3 7 9
3 1 3
3 4 7

2
35
8

N ≤ 100000, M ≤ 100000

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <stack>
#include <vector>
#include <queue>
#include <cstring>
#include <string>
#include <map>
#include <set>
using namespace std;

const int BufferSize = 1 << 16;
inline char Getchar() {
int l = fread(buffer, 1, BufferSize, stdin);
Tail = (Head = buffer) + l;
}
}
int x = 0, f = 1; char c = Getchar();
while(!isdigit(c)){ if(c == '-') f = -1; c = Getchar(); }
while(isdigit(c)){ x = x * 10 + c - '0'; c = Getchar(); }
return x * f;
}

#define maxn 100010
#define LL long long
int n, val[maxn];

void maintain(int L, int R, int o) {
int M = L + R >> 1, lc = o << 1, rc = lc | 1;
if(L == R) return ;
sumv[o] = ((sumv[lc] * timv[lc] % MOD + addv[lc] * (LL)(M - L + 1) % MOD) % MOD + (sumv[rc] * timv[rc] % MOD + addv[rc] * (LL)(R - M) % MOD) % MOD) % MOD;
return ;
}
void build(int L, int R, int o) {
timv[o] = 1;
if(L == R) sumv[o] = val[L];
else {
int M = L + R >> 1, lc = o << 1, rc = lc | 1;
build(L, M, lc); build(M+1, R, rc);
maintain(L, R, o);
}
return ;
}
void pushdown(int L, int R, int o) {
int M = L + R >> 1, lc = o << 1, rc = lc | 1;
LL len = (LL)(R - L + 1);
if(timv[o] != 1) {
(sumv[o] *= timv[o]) %= MOD;
if(L != R) {
(timv[lc] *= timv[o]) %= MOD; (addv[lc] *= timv[o]) %= MOD;
(timv[rc] *= timv[o]) %= MOD; (addv[rc] *= timv[o]) %= MOD;
}
timv[o] = 1;
}
sumv[o] += (addv[o] * len % MOD); if(sumv[o] >= MOD) sumv[o] -= MOD;
if(L != R) {
}
}
return ;
}
void update1(int L, int R, int o, int ql, int qr, LL v) {
pushdown(L, R, o);
if(ql <= L && R <= qr) (timv[o] *= v) %= MOD, (addv[o] *= v) %= MOD;
else {
int M = L + R >> 1, lc = o << 1, rc = lc | 1;
if(ql <= M) update1(L, M, lc, ql, qr, v);
if(qr > M) update1(M+1, R, rc, ql, qr, v);
}
maintain(L, R, o);
return ;
}
void update2(int L, int R, int o, int ql, int qr, LL v) {
pushdown(L, R, o);
if(ql <= L && R <= qr){ addv[o] += v; if(addv[o] >= MOD) addv[o] -= MOD; }
else {
int M = L + R >> 1, lc = o << 1, rc = lc | 1;
if(ql <= M) update2(L, M, lc, ql, qr, v);
if(qr > M) update2(M+1, R, rc, ql, qr, v);
}
maintain(L, R, o);
return ;
}
LL query(int L, int R, int o, int ql, int qr) {
pushdown(L, R, o);
if(ql <= L && R <= qr) return (sumv[o] * timv[o] % MOD + addv[o] * (LL)(R - L + 1) % MOD) % MOD;
int M = L + R >> 1, lc = o << 1, rc = lc | 1;
LL ans = 0;
if(ql <= M){ ans += query(L, M, lc, ql, qr); if(ans >= MOD) ans -= MOD; }
if(qr > M){ ans += query(M+1, R, rc, ql, qr); if(ans >= MOD) ans -= MOD; }
return ans;
}

int main() {
for(int i = 1; i <= n; i++) val[i] = read() % MOD;

build(1, n, 1);
while(q--) {
if(tp == 1) {
update1(1, n, 1, ql, qr, v);
}
if(tp == 2) {