2018 Multi-University Training Contest 1-H-RMQ Similar Sequence

(一)题面:

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 {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 Σbi (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≤1e6) -- 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×1e6.

 

Output

For each test case, output the answer as a value of a rational number modulo 1e9+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 1e9+7. Output such integer a between 0 and 1e9+6 that p−aq is divisible by 1e9+7.

 

Sample Input

3
3
1 2 3
3
1 2 1
5
1 2 3 2 1

 

Sample Output

250000002
500000004
125000001

 

(二)题意:

定义RMQ(A,l,r)为序列A中的[l,r]区间中最大值第一次出现的位置。两个长度相等的序列A和B,这两个序列{RMQ}相似的定义为对于任何一个相同的区间范围[l,r],两个序列有RMQ(A,l,r)=RMQ(B,l,r)。

现给出A序列,而B序列中的每一个数的取值为[0,1]之间的一个随机的实数。

如果B序列和A序列RMQ相似,那么B序列的权值为B序列中所有实数之和,否则权重为0。

问序列B权值的期望是多少?

 

(三)题解:

考虑到B序列中的数满足[0,1]区间的均匀分布,那么每一个数的取值的期望为1/2,故B序列的所有数的总和的期望为n/2,求接下来就是生成的B序列与A序列RMQ相似的概率,二者相乘就是结果。

我们将序列A建成一颗笛卡尔树,根据由于两个序列RMQ相似的要求,可以知道由B序列的得到的笛卡尔树的结构一定与A序列的笛卡尔树相同。由于树的结构相同,那么树的任意一个子树的结构也一样。我们考虑整颗树的根节点的值,由于该位置的值是n个数中最大的,故该位置的取值的概率为1/n。接下来再考虑其子节点,实际上求概率的方法就是一样的了--其子树的根节点的取值的概率为1/(其子树的节点数),然后将所有子树的概率相乘也就是构建整棵树的概率。

最终的期望就是二者的乘积:n/(2*∏size),然后mod 1e9+7就是结果。

 

(四)代码:

#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
#include<stack>
#include<algorithm>
#define LL long long
#define INF 0x3f3f3f3f
#define mod 1000000007
using namespace std;
const int maxn=2e6+10;
LL inv[maxn];
struct TreeNode{
    int l,r,val;
    TreeNode(){l=r=0;}
    void init(){l=r=0;}
}tree[maxn];
int stk[maxn];
int BuildTree(int n){
    for(int i=1,top=0;i<=n;i++){
        int k=top;
        while(k>0&&tree[stk[k-1]].val<tree[i].val)--k;
        if(k)tree[stk[k-1]].r=i;
        if(k<top)tree[i].l=stk[k];
        stk[k++]=i;
        top=k;
    }
    return stk[0];
}
LL ret=1;
int solve(int rt){
    int tot=1;
    if(!tree[rt].l&&!tree[rt].r)return 1;
    if(tree[rt].l)tot+=solve(tree[rt].l);
    if(tree[rt].r)tot+=solve(tree[rt].r);
    ret=ret*inv[tot]%mod;
    return tot;
}
int main(){
    inv[1]=1ll;
    for(int i=2;i<maxn;i++)inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod;
    int T,n;
    scanf("%d",&T);
    while(T--){
        ret=1;
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            tree[i].init();
            scanf("%d",&tree[i].val);
        }
        solve(BuildTree(n));
        printf("%lld\n",ret*inv[2]%mod*n%mod);
    }
    return 0;
}

 

(五)总结:

新技能get√--笛卡尔树。然而下次碰到可能还是不会用...,完全跟不上dl们的思维啊QWQ。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值