1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
| #include <iostream> #include <cmath> #include <vector> #define maxn 100010 #define maxs 400 #define ll long long using namespace std;
int n, m;
int blo, num, l[maxs], r[maxs], bl[maxn], p[maxs]; ll a[maxn], d[maxs], add[maxs]; vector<int> S[maxs]; void init_blo(int n) { blo = sqrt(n); num = (n + blo - 1) / blo; for (int i = 1; i <= n; ++i) bl[i] = (i - 1) / blo + 1; for (int i = 1; i <= num; ++i) { l[i] = (i - 1) * blo + 1; r[i] = i * blo; } r[num] = n; }
#define top S[k].back() #define dtop S[k][S[k].size() - 2] #define ind(i) S[i][p[i]] #define nxt(i) S[i][p[i] + 1] void maintain(int k) { while (p[k] < S[k].size() - 1 && a[ind(k)] + d[k] * ind(k) <= a[nxt(k)] + d[k] * nxt(k)) ++p[k]; }
void rebuild(int k) { for (int i = l[k]; i <= r[k]; ++i) a[i] += i * d[k] + add[k]; S[k].clear(); add[k] = d[k] = p[k] = 0; for (int i = l[k]; i <= r[k]; ++i) { while (S[k].size() > 1 && (a[i] - a[top]) * (top - dtop) >= (a[top] - a[dtop]) * (i - top)) S[k].pop_back(); S[k].push_back(i); } maintain(k); }
void update(int L, int R, ll v) { int Bl = bl[L], Br = bl[R]; if (Bl == Br) { for (int i = L; i <= R; ++i) a[i] += (i - L + 1) * v; return rebuild(Bl); } for (int i = L; i <= r[Bl]; ++i) a[i] += (i - L + 1) * v; rebuild(Bl); for (int i = Bl + 1; i < Br; ++i) { add[i] += (1 - L) * v, d[i] += v; maintain(i); } for (int i = l[Br]; i <= R; ++i) a[i] += (i - L + 1) * v; rebuild(Br); }
ll query(int L, int R) { int Bl = bl[L], Br = bl[R]; ll ans = a[1] + d[1] + add[1]; if (Bl == Br) { for (int i = L; i <= R; ++i) ans = max(ans, a[i] + i * d[Bl] + add[Bl]); return ans - (a[1] + d[1] + add[1]); } for (int i = L; i <= r[Bl]; ++i) ans = max(ans, a[i] + i * d[Bl] + add[Bl]); for (int i = Bl + 1; i < Br; ++i) ans = max(ans, a[ind(i)] + ind(i) * d[i] + add[i]); for (int i = l[Br]; i <= R; ++i) ans = max(ans, a[i] + i * d[Br] + add[Br]); return ans - (a[1] + d[1] + add[1]); }
inline void solve_1() { int x, y; cin >> x >> y; cout << query(x, y) << "\n"; }
inline void solve_2() { int x, y; cin >> x >> y; ll dx = x * d[bl[x]] + add[bl[x]], dy = y * d[bl[y]] + add[bl[y]]; ll ax = a[x], ay = a[y]; a[x] += (ay - ax) + (dy - dx); a[y] += (ax - ay) + (dx - dy); rebuild(bl[x]); if (bl[y] != bl[x]) rebuild(bl[y]); }
inline void solve_3() { int x, y, z; cin >> x >> y >> z; update(x, y, z); }
int main() { ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);
cin >> n >> m; init_blo(n); for (int i = 1; i <= n; ++i) cin >> a[i]; for (int i = 1; i <= num; ++i) rebuild(i); for (int i = 1; i <= m; ++i) { int opt; cin >> opt; switch (opt) { case 1 : solve_1(); break; case 2 : solve_2(); break; case 3 : solve_3(); break; } } return 0; }
|