HDU 6305 RMQ Similar Sequence

39 篇文章 0 订阅

大致题意:给你一个串A,定义RMQ相似串为,对任意区间[L,R],两个串RMQ所在位置相同。告诉你B串中每个元素服从于[0,1]上相互独立的均匀分布。B的权值定义为,当B与A串RMQ相似时,权值为所有元素之和,否则为0。现在问你B串的期望权值是多少。
串A可以看做n个数对,这n个数对之间有偏序,可以看做一个排列,B中两个数相等的几率为0,也可以看做一个数列。
发现这就是要求这两个数列构造出的笛卡尔树一样()。
又因为笛卡尔树满足点P的权值大于等于其子树内的所有值,
发现和拓扑序有点像,
树的拓扑序满足点P的拓扑序大于等于其子树内的所有点的拓扑序,
笛卡尔树的拓扑序列个数等于能构造出该笛卡尔树的序列个数!
又因为每个排列中数的和的期望为点数/2,算乘积就行。
树的拓扑序列个数怎么算,可以看我的另一篇博客:树的拓扑序列

AC code:

#include<cstdio>
#include<cstring>
#include<cctype>
#include<algorithm>
#define mod 1000000007
#define LL long long
using namespace std;

int sum(LL n){ return 1ll * n % mod * ((n+1) % mod) % mod * ((mod+1)/2) % mod; }
template<class T>inline void read(T &res)
{
    char ch;
    for(;!isdigit(ch=getchar()););
    for(res=ch-'0';isdigit(ch=getchar());res=res*10+ch-'0');
}

int main()
{
    LL n,m;
    int T;
    read(T);
    for(;T--;)
    {
        read(n);
        n--;
        m=0;
        for(int i=60;i>=0;i--)
            if(n>=(1ll << i+1) - 1)
            {
                n-=(1ll << i+1) - 1;
                m+=1ll << i;
            }
        int ans=1;
        if(n) ans=(ans + 1ll * n % mod * ((m+1) % mod) % mod);
        for(int tmp=1;m;m>>=1,tmp=1ll * tmp * 2 % mod)
            ans = (1ll * sum(m) * tmp + ans) % mod;
        printf("%d\n",ans);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值