P6406 [COCI2014-2015#2] Norma
艹
曰,口土 了。
十
\[\sum_{i=1}^N\sum_{j=i}^N(j-i+1) \cdot \min_{p=i}^j\{a_p\} \cdot \max_{q=i}^{j}\{a_q\}
\]
亚
心 式子。
反正我也想不出来分治,得题解而借鉴之。
在分治的时候,\([l, mid]\) 和 \([mid+1, r]\) 可以递归得到,那么考虑跨过 \(mid\) 的答案。
记录左边部分的最小值为 \(minn\), 最大值为 \(maxn\)。
考虑 \(p, q\)
- 使得 \(val_{p}\) 恰好小于等于 \(minn\) 且 \(val_{p-1}\) 大于 \(minn\)。
- 使得 \(val_{q}\) 恰好大于等于 \(maxn\) 且 \(val_{q-1}\) 小于 \(maxn\)。
那么拆开算呗。
现在假定 \(p \lt q\)
- 对于区间 \([mid+1, p-1]\) 你就有 \(minn \cdot maxn \cdot \sum_{j = mid + 1}^{p - 1} (j - i + 1)\)。
- 对于区间 \([p, q-1]\) 你就有 \(maxn \cdot \sum_{j=p}^{q-1}(min[j] \cdot (j-i+1)) = maxn \cdot \sum_{j=p}^{q-1}(min[j] \cdot j - min[j] \cdot i + min[j])\)。
- 对于区间 \([q, r]\) 你就有 \(\sum_{j=q}^{r}(min[j] \cdot max[j] \cdot (j-i+1)) = \sum_{j=q}^r (min[j] \cdot max[j] \cdot j - min[j] \cdot max[j] \cdot i + min[j] \cdot max[j])\)。
现在假定 \(p \ge q\)
- 对于区间 \([mid+1, q-1]\) 你就有 \(minn \cdot maxn \cdot \sum_{j = mid + 1}^{q - 1} (j - i + 1)\)。
- 对于区间 \([q, p-1]\) 你就有 \(minn \cdot \sum_{j=q}^{p-1}(max[j] \cdot (j-i+1)) = minn \cdot \sum_{j=q}^{p-1}(max[j] \cdot j - max[j] \cdot i + max[j])\)。
- 对于区间 \([p, r]\) 你就有 \(\sum_{j=p}^{r}(min[j] \cdot max[j] \cdot (j-i+1)) = \sum_{j=p}^r (min[j] \cdot max[j] \cdot j - min[j] \cdot max[j] \cdot i + min[j] \cdot max[j])\)。
然后你就知道需要维护 \(min[j], max[j],min[j] \cdot j, max[j] \cdot j, min[j] \cdot max[j], min[j] \cdot max[j] \cdot j\) 的前缀和。
然后馒馒抄式子。
/*
Name:
Author: Gensokyo_Alice
Date:
Description:
*/
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <vector>
#include <queue>
#include <stack>
#include <cmath>
#include <ctime>
#include <map>
#include <set>
using namespace std;
typedef long long ll;
const ll MAXN = 1e6+10, MOD = 1e9;
ll N, M, ans, val[MAXN], qzminn[MAXN], qzmaxn[MAXN], qzminni[MAXN], qzmaxni[MAXN], qzminnmaxn[MAXN], qzminnmaxni[MAXN];
void mmmm(ll);
ll summ(ll, ll);
void calc(ll, ll);
int main() {
scanf("%lld", &N);
for (ll i = 1; i <= N; i++) scanf("%lld", val+i);
calc(1, N);
printf("%lld\n", (ans % MOD + MOD) % MOD);
return 0;
}
ll summ(ll x, ll y) {return (x + y) * (y - x + 1) / 2 % MOD;}
void mmmm(ll x) {ans = ans + x + MOD >= MOD ? ans + x - MOD : ans + x;}
void calc(ll l, ll r) {
if (l == r) {
mmmm(val[l] * val[l] % MOD);
return ;
}
ll mid = (l + r) >> 1;
calc(l, mid); calc(mid + 1, r);
ll maxn = 0, minn = MOD;
qzminn[mid] = qzmaxn[mid] = qzminni[mid] = qzmaxni[mid] = qzminnmaxn[mid] = qzminnmaxni[mid] = 0;
for (ll i = mid + 1; i <= r; i++) {
maxn = max(maxn, val[i]), minn = min(minn, val[i]);
qzminn[i] = (qzminn[i-1] + minn) % MOD;
qzmaxn[i] = (qzmaxn[i-1] + maxn) % MOD;
qzminni[i] = (qzminni[i-1] + minn * i % MOD) % MOD;
qzmaxni[i] = (qzmaxni[i-1] + maxn * i % MOD) % MOD;
qzminnmaxn[i] = (qzminnmaxn[i-1] + minn * maxn % MOD) % MOD;
qzminnmaxni[i] = (qzminnmaxni[i-1] + minn * maxn % MOD * i % MOD) % MOD;
}
minn = MOD, maxn = 0;
for (ll p = mid + 1, q = mid + 1, i = mid; i >= l; i--) {
minn = min(minn, val[i]), maxn = max(maxn, val[i]);
while (p <= r && val[p] > minn) p++;
while (q <= r && val[q] < maxn) q++;
if (p < q) {
mmmm(minn * maxn % MOD * summ(mid - i + 2, p - i) % MOD);
mmmm(maxn * ((qzminni[q-1] - qzminn[q-1] * i % MOD + qzminn[q-1]) - (qzminni[p-1] - qzminn[p-1] * i % MOD + qzminn[p-1])) % MOD);
mmmm(((qzminnmaxni[r] - qzminnmaxn[r] * i % MOD + qzminnmaxn[r]) - (qzminnmaxni[q-1] - qzminnmaxn[q-1] * i % MOD + qzminnmaxn[q-1])) % MOD);
} else {
mmmm(minn * maxn % MOD * summ(mid - i + 2, q - i) % MOD);
mmmm(minn * ((qzmaxni[p-1] - qzmaxn[p-1] * i % MOD + qzmaxn[p-1]) - (qzmaxni[q-1] - qzmaxn[q-1] * i % MOD + qzmaxn[q-1])) % MOD);
mmmm(((qzminnmaxni[r] - qzminnmaxn[r] * i % MOD + qzminnmaxn[r]) - (qzminnmaxni[p-1] - qzminnmaxn[p-1] * i % MOD + qzminnmaxn[p-1])) % MOD);
}
}
}
希望我们都有一个光明的未来

浙公网安备 33010602011771号