RMQ Similar Sequence
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 255535/255535 K (Java/Others)
Total Submission(s): 204 Accepted Submission(s): 51
Problem Description
Chiaki has a sequence A={a1,a2,…,an}. Let RMQ(A,l,r) be the minimum i (l≤i≤r) such that ai is the maximum value in al,al+1,…,ar.
Two sequences A and B are called \textit{RMQ Similar}, if they have the same length n and for every 1≤l≤r≤n, RMQ(A,l,r)=RMQ(B,l,r).
For a given the sequence A={a1,a2,…,an}, define the weight of a sequence B={b1,b2,…,bn} be ∑i=1nbi (i.e. the sum of all elements in B) if sequence B and sequence A are RMQ Similar, or 0 otherwise. If each element of B is a real number chosen independently and uniformly at random between 0 and 1, find the expected weight of B.
Input
There are multiple test cases. The first line of input contains an integer T, indicating the number of test cases. For each test case:
The first line contains an integer n (1≤n≤106) -- the length of the sequence.
The second line contains n integers a1,a2,…,an (1≤ai≤n) denoting the sequence.
It is guaranteed that the sum of all n does not exceed 3×106.
Output
For each test case, output the answer as a value of a rational number modulo 109+7.
Formally, it is guaranteed that under given constraints the probability is always a rational number pq (p and q are integer and coprime, q is positive), such that q is not divisible by 109+7. Output such integer a between 0 and 109+6 that p−aq is divisible by 109+7.
Sample Input
3 3 1 2 3 3 1 2 1 5 1 2 3 2 1
Sample Output
250000002 500000004 125000001
Source
2018 Multi-University Training Contest 1
题意:定义RMQ(A,l,r)为:序列A中,满足A[i] = max(A[l],A[l+1],...,A[r])的最小的i。如果对于任意(l,r)都满足RMQ(A,l,r)=RMQ(B,l,r)则为A和B是RMQ Similar。现在出A序列,B序列的每个数都是0~1之间的实数,问满足与A是RMQ Similar的所有B序列中所有数之和的期望。
题解:不难看出如果A和B是RMQ Similar,则A和B的笛卡尔树同构。考虑B中的每个数是0~1之间的实数,因此出现相同数字的概率为0,可以假设B是每个数都不相同排列。设A的笛卡尔树每个子树的大小为sz[u],则任一B排列与A同构的概率是,因为B中每个数满足均匀分布,因此期望值为
,和的期望为
,因此满足与A同构的B中所有数之和的期望为
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
const int MX = 1e6 + 5;
struct node {
int val, sz;
int l, r, pre;
} t[MX];
stack<int>st;
void init (int n) {
for (int i = 0; i <= n; i++) t[i].l = t[i].r = t[i].pre = t[i].sz = 0;
t[0].val = INF;
while (!st.empty() ) st.pop();
st.push (0);
}
void build (int n) { //从右端插入
for (int i = 1; i <= n; i++) {
while (!st.empty() && t[st.top()].val < t[i].val) st.pop();
int pre = st.top();
t[i].pre = pre;
t[i].l = t[pre].r;
t[t[pre].r].pre = i;
t[pre].r = i;
st.push (i);
}
}
void dfs (int u) {
if (u == 0) return;
t[u].sz = 1;
dfs (t[u].l);
dfs (t[u].r);
t[u].sz += t[t[u].l].sz + t[t[u].r].sz;
}
LL inv[MX];
void init() {
inv[1] = 1;
for (int i = 2; i < MX; i++) inv[i] = inv[mod % i] * (mod - mod / i) % mod;
}
int main() {
//freopen ("in.txt", "r", stdin);
int T, n; cin >> T;
init();
while (T--) {
scanf ("%d", &n);
init (n);
for (int i = 1; i <= n; i++) scanf ("%d", &t[i].val);
build (n);
dfs (t[0].r);
LL ans = n * inv[2] % mod;
for (int i = 1; i <= n; i++) ans = ans * inv[t[i].sz] % mod;
printf ("%lld\n", ans);
}
return 0;
}