• HDU


    http://acm.hdu.edu.cn/showproblem.php?pid=6305

    题目

     对于A,B两个序列,任意的l,r,如果RMQ(A,l,r)=RMQ(B,l,r),B序列里的数为[0,1]的实数,B的重量为B的所有元素的和,否则为0。问你B的期望重量是多少。

    分析

     准备知识:笛卡尔树https://skywt.cn/posts/cartesian-tree/

    RMQ-Similar实际上就是A和B的笛卡尔树一样。于是这个题就是笛卡尔树同构的问题,假设A的笛卡尔树的子树大小为sz[u],那么序列B与A同构的概率为,因为B中的数满足均匀分布(因为B中的元素为[0,1]中的任意实数),所以每个位置的期望值为(0+1)/2,那么B的重量总和为n/2,所以B的重量的期望值为

    实际上对这题我还没完全懂,暂且记录一下吧。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #include<cstdlib>
    #include<cassert>
    #include<queue>
    #include<vector>
    #include<stack>
    using namespace std;
    typedef long long ll;
    const int maxn=1e6+10;
    const int inf=0x3f3f3f3f;
    const int mod=1e9+7;
    
    stack<int>st;
    ll inv[maxn];
    int n;
    
    struct node{
        int val,sz;
        int l,r,par;
    }t[maxn];
    
    
    void init()
    {
        for(int i=0;i<=n;i++)
            t[i].l=0,t[i].r=0,t[i].par=0,t[i].sz=0;//初始化
        t[0].val=inf;
        while(!st.empty())
            st.pop();
        st.push(0);
    }
    
    void build()
    {
        for(int i=1;i<=n;i++){
            while(!st.empty()&&t[st.top()].val<t[i].val)//从栈顶往栈底遍历,
                st.pop();
            int par=st.top();
            t[i].par=par;//i.par为st.pop()
            t[i].l=t[par].r;
            t[t[par].r].par=i;
            t[par].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;
    }
    
    void Inv(){//扩展gcd求逆元
        inv[1]=1;
        for(int i=2;i<maxn;i++)
            inv[i]=inv[mod%i]*(mod-mod/i)%mod;
    }
    
    int main()
    {
        int T;
        Inv();
        scanf("%d",&T);
        while(T--){
            scanf("%d",&n);
            init();
            for(int i=1;i<=n;i++)
                scanf("%d",&t[i].val);
            build();
            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
    ",ans);
        }
    }
  • 相关阅读:
    NOIP模拟题——小L的珍珠挂饰
    NOIP模拟题——小L的牛栏
    NOIP模拟题——小L的二叉树
    NOIP模拟题——愉快的logo设计
    NOIP模拟题——复制&粘贴2
    NOIP模拟题——Landscaping
    poj3264
    RMQ_ST算法
    Count Colour_poj2777(线段树+位)
    I Hate It(hdu1754)(线段树区间最大值)
  • 原文地址:https://www.cnblogs.com/fht-litost/p/9551231.html
Copyright © 2020-2023  润新知