zoukankan      html  css  js  c++  java
  • hdu 6305 RMQ Similar Sequence——概率方面的思路+笛卡尔树

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

    看题解,得知:

    0~1内随机取实数,取到两个相同的数的概率是0,所以认为 b 序列是一个排列。

    两个序列“RMQ相似”,意为它们的笛卡尔树同构。注意有相同值的时候,后出现的应该位于先出现的的子树中。

    一个排列的笛卡尔树与给定笛卡尔树同构的概率是 ( prodlimits_{i=1}^{n}frac{1}{siz_i} ) ,其中 ( siz_i ) 表示树上编号为 i 的点的子树大小。

      不过不太明白为什么是这样。

    一个数的期望值是 ( frac{1}{2} ) ,所以整个序列的期望值就是 ( frac{n}{2} ) ,乘上刚才那个同构概率即可。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define ll long long
    using namespace std;
    int rdn()
    {
      int ret=0;bool fx=1;char ch=getchar();
      while(ch>'9'||ch<'0'){if(ch=='-')fx=0;ch=getchar();}
      while(ch>='0'&&ch<='9')ret=ret*10+ch-'0',ch=getchar();
      return fx?ret:-ret;
    }
    const int N=1e6+5,mod=1e9+7;
    int pw(int x,int k)
    {int ret=1;while(k){if(k&1)ret=(ll)ret*x%mod;x=(ll)x*x%mod;k>>=1;}return ret;}
    
    int n,a[N],ans,inv[N];
    int sta[N],top,ls[N],rs[N],fa[N];
    void init()
    {
      int n=1e6;
      for(int i=1;i<=n;i++)inv[i]=pw(i,mod-2);
    }
    void get_dkr()
    {
      top=0;
      for(int i=1;i<=n;i++)
        {
          ls[i]=rs[i]=fa[i]=0;
          while(top&&a[sta[top]]<a[i])
        ls[i]=sta[top--];
          fa[i]=sta[top]; sta[++top]=i;
          rs[fa[i]]=i; if(ls[i])fa[ls[i]]=i;
        }
    }
    int dfs(int cr)
    {
      if(!cr)return 0;
      int siz=dfs(ls[cr])+dfs(rs[cr])+1;
      ans=(ll)ans*inv[siz]%mod;
      return siz;
    }
    int main()
    {
      int T=rdn();init();
      while(T--)
        {
          n=rdn();for(int i=1;i<=n;i++)a[i]=rdn();
          get_dkr(); ans=(ll)n*inv[2]%mod; dfs(rs[0]);
          printf("%d
    ",ans);
        }
      return 0;
    }
  • 相关阅读:
    Splay复习
    带权并查集复习-HDU3038
    罗素悖论-图灵停机问题
    数独解法c++实现
    状压DP NOI2001 炮兵阵地
    区间第k大数
    分块随笔T2
    分块感想
    webkit的高级属性
    设计模式
  • 原文地址:https://www.cnblogs.com/Narh/p/10415004.html
Copyright © 2011-2022 走看看