# 洛谷P5113 Sabbat of the witch

### 代码

#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#define file(x) freopen(#x".in", "r", stdin), freopen(#x".out", "w", stdout)

{
int data = 0, w = 1; char ch = getchar();
while (ch != '-' && (ch < '0' || ch > '9')) ch = getchar();
if (ch == '-') w = -1, ch = getchar();
while (ch >= '0' && ch <= '9') data = data * 10 + (ch ^ 48), ch = getchar();
return data * w;
}

using ll = long long;
const int N(1e5 + 10), sqrtN(500);
struct node { int l, r, v; } q[N];
int n, m, Len, a[N], del[N], bel[N], lst[sqrtN], pos[sqrtN], L[sqrtN], R[sqrtN];
ll ans[sqrtN];
std::vector<int> v[N], op[sqrtN];
std::vector<int> num[sqrtN];
std::vector<ll> sum[sqrtN];

void Radix_Sort(const int &n, std::pair<int, int> *a)
{
static int r1[256], r2[256];
static std::pair<int, int> b[sqrtN];
std::pair<int, int> *j, *tar; int i, tmp;
std::memset(r1, 0, sizeof r1), std::memset(r2, 0, sizeof r2);
for (j = a + 1, tar = a + n + 1; j != tar; j++)
tmp = j -> first, ++r1[tmp & 0xff], ++r2[(tmp >> 8) & 0xff];
for (i = 1; i < 256; i++) r1[i] += r1[i - 1], r2[i] += r2[i - 1];
for (j = a + n; j != a; j--) b[r1[(j -> first) & 0xff]--] = *j;
for (j = b + n; j != b; j--) a[r2[((j -> first) >> 8) & 0xff]--] = *j;
}

#define tim(i) (v[i].empty() ? 0 : v[i].back())
#define val(i) (v[i].empty() ? a[i] : q[v[i].back()].v)
void rebuild(int id)
{
static std::pair<int, int> g[sqrtN]; int l = L[id], r = R[id], c = 0;
for (int i = l; i <= r; i++) g[++c] = std::make_pair(tim(i), i);
Radix_Sort(c, g), num[id].resize(c), sum[id].resize(c + 1);
for (int i = c - 1; i >= 0; i--)
num[id][i] = g[i + 1].second, sum[id][i] = sum[id][i + 1] + val(g[i + 1].second);
lst[id] = op[id].empty() ? 0 : op[id].back();
for (pos[id] = 0; pos[id] < c; pos[id]++) if (g[pos[id] + 1].first >= lst[id]) break;
--pos[id], ans[id] = 1ll * (pos[id] + 1) * q[lst[id]].v + sum[id][pos[id] + 1];
}

void Cover(int id)
{
int l = q[id].l, r = q[id].r;
if (bel[l] == bel[r]) { for (int i = l; i <= r; i++) v[i].push_back(id); return rebuild(bel[l]); }
for (int i = l; bel[i] == bel[l]; i++) v[i].push_back(id); rebuild(bel[l]);
for (int i = r; bel[i] == bel[r]; i--) v[i].push_back(id); rebuild(bel[r]);
for (int i = bel[l] + 1; i < bel[r]; i++)
op[i].push_back(id), ans[i] = 1ll * (R[i] - L[i] + 1) * q[id].v;
}

ll Sum(int l, int r)
{
ll ans = 0;
#define do_node(x) ans += (tim(x) >= t ? val(x) : q[t].v)
#define tblk(i) (op[i].empty() ? 0 : op[i].back())
if (bel[l] == bel[r]) { for (int i = l, t = tblk(bel[i]); i <= r; i++) do_node(i); return ans; }
for (int i = l, t = tblk(bel[i]); bel[i] == bel[l]; i++) do_node(i);
for (int i = r, t = tblk(bel[i]); bel[i] == bel[r]; i--) do_node(i);
for (int i = bel[l] + 1; i < bel[r]; i++) ans += ::ans[i];
#undef tblk
#undef do_node
return ans;
}

void Undo(int id)
{
int l = q[id].l, r = q[id].r; del[id] = 1;
#define do_node(x) while (!v[x].empty() && del[v[x].back()]) v[x].pop_back()
if (bel[l] == bel[r]) { for (int i = l; i <= r; i++) do_node(i); return rebuild(bel[l]); }
for (int i = l; bel[i] == bel[l]; i++) do_node(i); rebuild(bel[l]);
for (int i = r; bel[i] == bel[r]; i--) do_node(i); rebuild(bel[r]);
for (int i = bel[l] + 1; i < bel[r]; i++)
{
while (!op[i].empty() && del[op[i].back()]) op[i].pop_back();
int t = op[i].empty() ? 0 : op[i].back();
if (t > lst[i]) ans[i] = 1ll * (R[i] - L[i] + 1) * q[t].v;
else
{
while (pos[i] >= 0 && tim(num[i][pos[i]]) >= t) --pos[i];
ans[i] = 1ll * (pos[i] + 1) * q[t].v + sum[i][pos[i] + 1];
}
}
#undef do_node
}

int main()
{
#ifndef ONLINE_JUDGE
file(cpp);
#endif
for (int i = 1; i <= n; i++) a[i] = read();
for (int i = 1; i <= n; i++) bel[i] = (i - 1) / Len + 1;
for (int i = 1; i <= n; i++) R[bel[i]] = i;
for (int i = n; i; i--) L[bel[i]] = i;
for (int i = 1; i <= bel[n]; i++) rebuild(i);
int cnt = 0; ll ans = 0;
while (m--)
{
int op = read(), l, r;