题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6305
意识到RMQ相同的含义就是序列的相对大小关系保持一致,而相同的大小关系建立出的笛卡尔树相同(特殊的不是笛卡尔树,而是建树的方式)。
考虑B数组的排列中能够符合A数组构成的笛卡尔树的概率为
1/∏sz[i]
1
/
∏
s
z
[
i
]
,可以简单理解为,在对应笛卡尔树的节点上,当前位置作为这个子树中的最大值的概率是
1/sz[i]
1
/
s
z
[
i
]
,因此得到上式,B数组取值任取且均匀分布,因此对于每种方案的期望值都是
n/2
n
/
2
,所以答案即为
1/(2∗∏sz[i])
1
/
(
2
∗
∏
s
z
[
i
]
)
。
#define others
#ifdef poj
#include <iostream>
#include <cstring>
#include <cmath>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <string>
#include <map>
#include <set>
#endif // poj
#ifdef others
#include <bits/stdc++.h>
#include <ext/rope>
#include <ext/pb_ds/priority_queue.hpp>
#endif // others
//#define file
#define all(x) x.begin(), x.end()
using namespace std;
using namespace __gnu_pbds;
using namespace __gnu_cxx;
#define eps 1e-8
const double pi = acos(-1.0);
typedef long long LL;
typedef long long ll;
typedef unsigned long long ULL;
void umax(int &a, int b) {
a = max(a, b);
}
void umin(int &a, int b) {
a = min(a, b);
}
int dcmp(double x) {
return fabs(x) <= eps?0:(x > 0?1:-1);
}
void file() {
freopen("data_in.txt", "r", stdin);
freopen("data_out.txt", "w", stdout);
}
const LL mod = 1e9+7;
ll powmod(ll a,ll b) {ll res=1;a%=mod; assert(b>=0); for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
namespace solver {
const int maxn = 1e6+10;
const LL mod = 1e9 + 7;
int t, n;
LL Inv[maxn];
void init() {
int p = mod;
Inv[1] = 1;
for (int i = 2, k; i < maxn; ++i) {
t = p / i;
k = p % i;
Inv[i] = (p - t) * Inv[k] % p;
}
}
struct Tree {
int val;
int l, r;
Tree() {
l = r = 0;
}
} tr[maxn];
stack<int> stk;
int rt;
void ins(int x) {
while (!stk.empty() && tr[x].val > tr[stk.top()].val) {
stk.pop();
}
if (stk.empty()) {
tr[x].l = rt;
rt = x;
} else {
int tp = stk.top();
tr[x].l = tr[tp].r;
tr[tp].r = x;
}
stk.push(x);
}
LL res;
int dfs(int x) {
int sz = 1;
if (tr[x].l) sz += dfs(tr[x].l);
if (tr[x].r) sz += dfs(tr[x].r);
res = (res * Inv[sz]) % mod;
return sz;
}
void dfs_destory(int x) {
if (tr[x].l) dfs_destory(tr[x].l);
if (tr[x].r) dfs_destory(tr[x].r);
tr[x].l = tr[x].r = tr[x].val = 0;
}
void solve() {
init();
cin >> t;
while (t--) {
while(!stk.empty()) stk.pop();
rt = 1;
cin >> n;
cin >> tr[1].val;
stk.push(1);
for (int i = 2; i <= n; i++) {
cin >> tr[i].val;
ins(i);
}
res = n * Inv[2] % mod;
dfs(rt);
cout << res << '\n';
dfs_destory(rt);
}
}
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
// file();
solver::solve();
return 0;
}