HDU 6305(笛卡尔树)

RMQ Similar Sequence

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 255535/255535 K (Java/Others)
Total Submission(s): 882    Accepted Submission(s): 281


 

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相似,说明他们的笛卡尔树应该是长得一样的。

考虑到这里的bi两两不同,说明是求bi的拓扑序个数

对于i的子树,i总是要为这个子树的最大值,概率为1/sz(i)

所以拓扑序的个数为n!/(sz(1)sz(2)...sz(n))

每个位置的期望为(0+1)/2

所以总的期望为n/(2*sz(1)sz(2)...sz(n))

预处理一下逆元,套上笛卡尔树的模板就可以了

#include
#define mp make_pair
#define fir first
#define se second
#define ll long long
#define pb push_back
using namespace std;
const int maxn=1e6+10;
const ll mod=1e9+7;
const int maxm=1e6+10;
const double eps=1e-7;
const int inf=0x3f3f3f3f;
int l[maxn],r[maxn],vis[maxn];
int sz[maxn];
int stk[maxn];
ll inv[maxn];
int n;
int a[maxn];
void init(){
    inv[1]=1;
    for (int i=2;i0&&a[stk[k-1]]

 

你可能感兴趣的:(hdu)