杭电多校第一场 1008 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): 466    Accepted Submission(s): 131


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

扫描二维码关注公众号,回复: 2444377 查看本文章

题目大意:题目给出对于一个数组A的RMQ(A,l,r)的定义为A[l],A[l+1],...,A[r]中最大值的位置(如果有多个最大值,那么取位置最小的值)。再给出RMQ相似的定义,对于数组A和数组B,如果对于任意的l,r,RMQ(A,l,r)都等于RMQ(B,l,r),那么这两个数组就是RMQ相似的。现在给出数组A,要你求出一个与A是RMQ相似的数组B,同时数组B内的元素都是[0,1]内的实数,输出\sum_{i=1}^{n}B_{i}的期望。

题目思路:本题需要用到一个数据结构——笛卡尔树,笛卡尔树的简单性质为:

1.树中的元素满足二叉搜索树性质,要求按照中序遍历得到的序列为原数组序列(左儿子的id值小于自己,右儿子的id值大于自己)

2.树中节点满足堆性质,节点的val值要小于其左右子节点的val值

因为这个题的RMQ相似的定义为任意区间[l,r]的最大值的位置相同,那么就可以转化为求A和B两个数组所形成的笛卡尔树同构。

(由于要求最大值,我们只需要把数组内的值变成负数就行了,依旧满足笛卡尔树的性质)

举个简单的例子

比如A={1,3,2,5,4},B={0.2,0.5,0.3,0.7,0.6}(根据题目定义,这两个数组是RMQ相似的)

两个数组形成的笛卡尔树分别为

可以看出这两棵笛卡尔树是同构的。

那么要如何计算最终的结果呢还是取A={1,3,2,5,4}为例,由于B取得相同元素的概率为0,所以我们假设B数组内的值全部不相同。

对于以-5为根节点的子树,我们要使得B数组构造的笛卡尔树所对应的节点为子树中的最大值,因为这个子树有5个结点,所以就有1/5的概率将这个位置放为最大值;同理,对于以-3为根节点,我们有1/3的概率将这个位置放为最大值,以此类推,构造出的B数组符合相同与A的笛卡尔树同构的概率为\prod\frac{1}{size},size为所有子树的大小。对于B数组内每个元素的取值,有均匀分布的定理的,每个元素取值的期望为1/2,那么一整个序列的期望就为n/2,最终的答案就为\frac{n}{2\prod\frac{1}{size}}。最终答案记得对1e9+7取模。

具体实现看代码(笛卡尔树模板和线性求逆元的板子都是参照杜教的板子,杜教tql,orz)

#include <bits/stdc++.h>
#define fi first
#define se second
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define lowbit(x) x&-x
#define MP make_pair
#define pb push_back
#define debug(x) cout<<x<<"= "<<x<<endl;
#define FIN freopen("in.txt","r",stdin);
using namespace std;
typedef long long ll;
typedef vector<int> vi;
typedef pair<int,int>pii;
const int mod=1e9+7;
const int inf=0x3f3f3f3f;
const ll infll=0x3f3f3f3f3f3f3f3f;
const int MX=1e6+7;

int n;
int s[MX],l[MX],r[MX];
bool vis[MX];
ll inv[MX],res;
pii a[MX];

int dfs(int rt){
    int sz=1;
    if(l[rt]) sz+=dfs(l[rt]);
    if(r[rt]) sz+=dfs(r[rt]);
    res=res*inv[sz]%mod;
    return sz;
}
void build(int _n){
    int top=0;
    for(int i=0;i<=_n;i++) 
        l[i]=r[i]=vis[i]=0;
    for(int i=1;i<=_n;i++){
        int k=top;
        while(k>0 && a[s[k-1]]>a[i]) k--;
        if(k) r[s[k-1]]=i;
        if(k<top) l[i]=s[k];
        s[k++]=i;
        top=k;
    }
    for(int i=1;i<=n;i++) vis[l[i]]=vis[r[i]]=1;
}

int main(){
    int _;
    inv[1]=1;
    for(int i=2;i<MX;i++) inv[i]=inv[mod%i]*(mod-mod/i)%mod;
    for(scanf("%d",&_);_;_--){
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            int x;scanf("%d",&x);
            a[i]=MP(-x,i);
        }
        res=inv[2]*n%mod;
        build(n);
        int rt=0;
        for(int i=1;i<=n;i++){
            if(vis[i]==0)
                rt=i;
        }
        dfs(rt);
        printf("%lld\n",res);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/lee_w_j__/article/details/81182212