HDU多校第四场1005 Didn‘t I Say to Make My Abilities Average in the Next Life?! 单调栈+莫队
Posted kaka0010
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU多校第四场1005 Didn‘t I Say to Make My Abilities Average in the Next Life?! 单调栈+莫队相关的知识,希望对你有一定的参考价值。
原题链接:https://acm.hdu.edu.cn/showproblem.php?pid=6989
题意
给你一个数列,定义一个区间的平均值为(Max+Min)/2,询问一个区间的所有平均值的期望是多少。
分析
我们把题目的式子化简一下,就是
∑
m
a
x
+
∑
m
i
n
2
∗
l
e
n
∗
(
l
e
n
+
1
)
2
\\frac{\\sum max+\\sum min}{2*\\frac{len*(len+1)}{2}}
2∗2len∗(len+1)∑max+∑min
=
∑
m
a
x
+
∑
m
i
n
l
e
n
∗
(
l
e
n
+
1
)
=\\frac{\\sum max+\\sum min}{len*(len+1)}
=len∗(len+1)∑max+∑min
这样我们只需要求出所有子区间的最大值和所有子区间的最小值之和就可以了。
对于这类问题,我在这篇文章中详细解释过(双倍经验 )点这里
接下来就是套个板子的事情。
Code
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned int ul;
typedef pair<ll, ll> PII;
const ll inf = 1e18;
const int N = 2e5 + 10;
const int M = 1e6 + 10;
const ll mod = 1e9 + 7;
const double eps = 1e-8;
#define lowbit(i) (i & -i)
#define Debug(x) cout << (x) << endl
#define fi first
#define se second
#define mem memset
#define endl '\\n'
namespace StandardIO {
template<typename T>
inline void read(T &x) {
x = 0; T f = 1;
char c = getchar();
for (; c < '0' || c > '9'; c = getchar()) if (c == '-') f = -1;
for (; c >= '0' && c <= '9'; c = getchar()) x = x * 10 + c - '0';
x *= f;
}
template<typename T>
inline void write(T x) {
if (x < 0) putchar('-'), x *= -1;
if (x >= 10) write(x / 10);
putchar(x % 10 + '0');
}
}
namespace Comb {
ll f[N];
ll ksm(ll a, ll b) {
ll res = 1, base = a;
while (b) {
if (b & 1) res = res * base % mod;
base = base * base % mod;
b >>= 1;
}
return res;
}
void init() {
f[0] = 1;
for (ll i = 1; i < N; i++) f[i] = f[i - 1] * i % mod;
}
ll C(ll a, ll b) {
if (a < 0 || b < 0 || b > a) return 0;
return f[a] * ksm(f[a - b], mod - 2) % mod * ksm(f[b], mod - 2) % mod;
}
}
namespace ST {
int mi[N][21], ma[N][21], lg[N], a[N];
int cmp1(int x, int y) {
return a[x] < a[y] ? x : y;
}
int cmp2(int x, int y) {
return a[x] > a[y] ? x : y;
}
void init(int n) {
for (int i = 1; i <= n; i++) {
cin >> a[i];
ma[i][0] = mi[i][0] = i, lg[i] = log2(i);
}
for (int i = 1; i <= 20; i++) {
for (int j = 1; j + (1 << i) - 1 <= n; j++) {
mi[j][i] = cmp1(mi[j][i - 1], mi[j + (1 << (i - 1))][i - 1]);
ma[j][i] = cmp2(ma[j][i - 1], ma[j + (1 << (i - 1))][i - 1]);
}
}
}
int qry_mi(int l, int r) {
int k = lg[r - l + 1];
return a[cmp1(mi[l][k], mi[r - (1 << k) + 1][k])];
}
int qry_ma(int l, int r) {
int k = lg[r - l + 1];
return a[cmp2(ma[l][k], ma[r - (1 << k) + 1][k])];
}
int qry_pmi(int l, int r) {
int k = lg[r - l + 1];
return cmp1(mi[l][k], mi[r - (1 << k) + 1][k]);
}
int qry_pma(int l, int r) {
int k = lg[r - l + 1];
return cmp2(ma[l][k], ma[r - (1 << k) + 1][k]);
}
}
using namespace ST;
using namespace Comb;
int n, m, pos[N], lmi[N], rmi[N], lma[N], rma[N], stk[N], tp;
ll f1[N], f2[N], f3[N], f4[N], ans[N], res;
struct Query {
int id, l, r;
}q[N];
bool cmp(Query x, Query y) {
if (pos[x.l] == pos[y.l]) return x.r < y.r;
else return pos[x.l] < pos[y.l];
}
void add_right(int L, int R) {
int p1 = qry_pmi(L, R);
int p2 = qry_pma(L, R);
res += 1ll*(p1 - L + 1) * a[p1] % mod + f1[R] - f1[p1];
res = (res % mod + mod) % mod;
res += 1ll*(p2 - L + 1) * a[p2] % mod + f3[R] - f3[p2];
res = (res % mod + mod) % mod;
}
void add_left(int L, int R) {
int p1 = qry_pmi(L, R);
int p2 = qry_pma(L, R);
res += 1ll*(R - p1 + 1) * a[p1] % mod + f2[L] - f2[p1];
res = (res % mod + mod) % mod;
res += 1ll*(R - p2 + 1) * a[p2] % mod + f4[L] - f4[p2];
res = (res % mod + mod) % mod;
}
void sub_right(int L, int R) {
int p1 = qry_pmi(L, R);
int p2 = qry_pma(L, R);
res -= 1ll*(p1 - L + 1) * a[p1] % mod + f1[R] - f1[p1];
res = (res % mod + mod) % mod;
res -= 1ll*(p2 - L + 1) * a[p2] % mod + f3[R] - f3[p2];
res = (res % mod + mod) % mod;
}
void sub_left(int L, int R) {
int p1 = qry_pmi(L, R);
int p2 = qry_pma(L, R);
res -= 1ll*(R - p1 + 1) * a[p1] % mod + f2[L] - f2[p1];
res = (res % mod + mod) % mod;
res -= 1ll*(R - p2 + 1) * a[p2] % mod + f4[L] - f4[p2];
res = (res % mod + mod) % mod;
}
inline void solve() {
int T; cin >> T; while (T--) {
cin >> n >> m;
init(n);
int siz = sqrt(n);
for (int i = 1; i <= n; i++) pos[i] = i / siz;
for (int i = 1; i <= m; i++) {
cin >> q[i].l >> q[i].r;
q[i].id = i;
}
sort(q + 1, q + m + 1, cmp);
tp = 0;
for (int i = 1; i <= n; i++) {//left samll
while (tp && a[stk[tp]] > a[i]) tp--;
if (!tp) lmi[i] = 0;
else lmi[i] = stk[tp];
stk[++tp] = i;
}
tp = 0;
for (int i = n; i >= 1; i--) {//right small
while (tp && a[stk[tp]] > a[i]) tp--;
if (!tp) rmi[i] = n + 1;
else rmi[i] = stk[tp];
stk[++tp] = i;
}
tp = 0;
for (int i = 1; i <= n; i++) {//left big
while (tp && a[stk[tp]] < a[i]) tp--;
if (!tp) lma[i] = 0;
else lma[i] = stk[tp];
stk[++tp] = i;
}
tp = 0;
for (int i = n; i >= 1; i--) {//right big
while (tp && a[stk[tp]] < a[i]) tp--;
if (!tp) rma[i] = n + 1;
else rma[i] =<以上是关于HDU多校第四场1005 Didn‘t I Say to Make My Abilities Average in the Next Life?! 单调栈+莫队的主要内容,如果未能解决你的问题,请参考以下文章
杭电2018多校第四场(2018 Multi-University Training Contest 4) 1005.Problem E. Matrix from Arrays (HDU6336) -
hdu多校第四场1001 (hdu6614) AND Minimum Spanning Tree 签到
2020杭电多校第四场 Go Running 最小点覆盖等于二分图最大匹配数
2019杭电多校第四场hdu6621 K-th Closest Distance(二分答案+主席树)
HDU多校4 - 6989 Didn‘t I Say to Make My Abilities Average in the Next Life?!(单调栈)