• 2020牛客寒假算法基础集训营3.E.牛牛的随机数(数位dp拆位算贡献)


    题目链接

    题解思路:首先观察题目需要我们求的是什么——期望,那我们其实只要算出每一项的贡献,并把他们加起来,最后再除去总数即可。那么这么大的数据范围怎么算每一项的贡献呢?这里就需要用到数位dp了。由于题目要求的是异或值的期望,因此二进制的数位dp是最好的选择,我们只需要将其拆位就能得到每一位是1或是0的数量。最终答案其实也就是∑(cnta0*cntb1+cnta1*cntb0)*(1<<i),这里面的cnta0代表的是a区间,第i位为0的数量,以此类推,答案就很显然了。


    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> PII;
    #define ls l,mid,rt<<1
    #define rs mid+1,r,rt<<1|1
    #define endl '
    '
    const int MAXN = 1e6+10;
    const double EPS = 1e-12;
    const ll mod = 1e9+7;
    
    int T;
    ll l1,r1,l2,r2;
    ll dp[70][70][2],a[70];
    
    ll dfs(int pos,int sta,int k,bool limit){
        if(pos==0)return sta;
        if(!limit&&dp[pos][k][sta]!=-1)return dp[pos][k][sta];
        int up=limit ? a[pos] : 1;
        ll ans=0;
        for(int i=0;i<=up;i++)
            ans+=dfs(pos-1,sta||(pos==k&&i!=0),k,limit&&i==a[pos]);
        if(!limit)dp[pos][k][sta]=ans;
        return ans;
    }
    
    ll solve(ll x,int k){
        int pos=0;
        while(x){
            a[++pos]=x%2;
            x/=2;
        }
        return dfs(pos,0,k,1);
    }
    
    ll poww(ll a,ll b){
        ll ans=1;
        while(b){
            if(b&1)ans=ans*a%mod;
            a=a*a%mod;
            b/=2;
        }
        return ans;
    }
    
    int main()
    {
        scanf("%d",&T);
        while(T--){
            memset(dp,-1,sizeof(dp));
            scanf("%lld %lld %lld %lld",&l1,&r1,&l2,&r2);
            ll now=1,ans=0;
            for(int i=1;i<70;i++){
                ll ca0=solve(r1,i)-solve(l1-1,i),ca1=r1-l1+1-ca0;
                ll cb0=solve(r2,i)-solve(l2-1,i),cb1=r2-l2+1-cb0;
                ca1%=mod,ca0%=mod,cb1%=mod,cb0%=mod;
                ans=(ans+(ca1*cb0%mod+ca0*cb1%mod)%mod*now%mod)%mod;
                now=now*2%mod;
            }
            ll x=(r1-l1+1)*(r2-l2+1)%mod;
            cout<<ans*poww(x,mod-2)%mod<<endl;
        }
    }
  • 相关阅读:
    索引使用及注意事项
    Explain详解与索引
    JVM常量池了解
    认识Mysql索引
    JVM调优工具及了解
    JVM垃圾收集器
    JVM垃圾回收相关算法
    JVM字节码文件结构剖析
    JVM对象创建与内存分配机制
    JVM内存参数设置
  • 原文地址:https://www.cnblogs.com/Mmasker/p/12642639.html
Copyright © 2020-2023  润新知