HDU-6305 RMQ Similar Sequence(笛卡爾樹+期望)

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同構的概率是\prod_{1}^{n} \frac{1}{sz[i]},因爲B中每個數滿足均勻分佈,因此期望值爲\frac{1}{2},和的期望爲\frac{n}{2},因此滿足與A同構的B中所有數之和的期望爲\frac{n}{2\prod_{1}^{n}sz[i]}

#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;
}

 

發佈了291 篇原創文章 · 獲贊 104 · 訪問量 17萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章