给定长度为$n$的序列:$a_1,a_2,\ldots ,a_n$,记为$a[1:n]$。类似地,$a[l:r](1\le l \le r \le N)$是指序列:$a_l,a_{l+1},\ldots , a_{r-1},a_r$。若$1 \le l \le s \le t \le r \le n$,则称$a[s:t]$是$a[l:r]$的子序列。
现在有$q$个询问,每个询问给定两个数$l$和$r$,$1 \le l \le r \le n$,求$a[l:r]$的不同子序列的最小值之和。
int n, q; int a[maxn], pre[maxn], suf[maxn]; int stk[maxn], top; int ST[maxn][18], LO2[maxn], PO2[20]; ll ftr[maxn], ftl[maxn], sfr[maxn], sfl[maxn];
inlineintrd(){ registerint x = 0, f = 0, c = getchar(); while (!isdigit(c)) { if (c == '-') f = 1; c = getchar(); } while (isdigit(c)) x = x * 10 + (c ^ 48), c = getchar(); return f ? -x : x; } inlineintquery(int l, int r){ int delt = LO2[r - l + 1]; return (a[ST[l][delt]] < a[ST[r - PO2[delt] + 1][delt]] ? ST[l][delt] : ST[r - PO2[delt] + 1][delt]); }
intmain(){ n = rd(); q = rd(); LO2[1] = 0; for (int i = 2; i <= n; ++i) LO2[i] = (LO2[i >> 1] + 1); PO2[0] = 1; for (int i = 1; i < 18; ++i) PO2[i] = (PO2[i - 1] << 1); for (int i = 1; i <= n; ++i) { a[i] = rd(); ST[i][0] = i; } for (int j = 1; j <= LO2[n]; ++j) for (int i = 1; i <= n - PO2[j - 1] + 1; ++i) ST[i][j] = (a[ST[i][j - 1]] < a[ST[i + PO2[j - 1]][j - 1]] ? ST[i][j - 1] : ST[i + PO2[j - 1]][j - 1]);
a[0] = a[n + 1] = 0x3f3f3f3f; for (int i = 1; i <= n; ++i) { while (top && a[stk[top]] > a[i]) suf[stk[top]] = i, top--; pre[i] = stk[top]; stk[++top] = i; } while (top) pre[stk[top]] = stk[top - 1], suf[stk[top]] = n + 1, top--; for (int i = 1; i <= n; ++i) ftr[i] = ftr[pre[i]] + (ll)a[i] * (i - pre[i]), sfr[i] = sfr[i - 1] + ftr[i]; for (int i = n; i; --i) ftl[i] = ftl[suf[i]] + (ll)a[i] * (suf[i] - i), sfl[i] = sfl[i + 1] + ftl[i]; int l, r, pos; while (q--) { l = rd(); r = rd(); pos = query(l, r); ll ans = 1ll * a[pos] * (pos - l + 1) * (r - pos + 1) + (ll)sfr[r] - (ll)sfr[pos] - 1ll * ftr[pos] * (r - pos) + (ll)sfl[l] - (ll)sfl[pos] - 1ll * ftl[pos] * (pos - l); printf("%lld\n", ans); } return0; }