zoukankan      html  css  js  c++  java
  • 熊猫(i)

    题目描述

    熊猫喜欢吃数,熊猫对与每个数都有他独特的评价。具体来说,熊猫对数 xx 的评价是个四元组 (a, b, c, d)(a,b,c,d),计算方式如下:

    首先将 xx 写成二进制形式(不含前导零),然后将这作为一个字符串,那么 a =a= 子串 “00”00” 的数量,b =b= 子串 “01”01” 的数量,c =c= 子串 “10”10” 的数量,d =d= 子串 “11”11” 的数量。

    现在熊猫想吃掉区间 [A,B] 之间所有评价是 (a, b, c, d)(a,b,c,d) 的数,由于你被熊猫抓了起来,所以他要你回答他能吃到多少个数。如果你回答不出,他就只好吃你。

    输入格式

    第一行一个 0101 串为 AA 的二进制表示。

    第一行一个 0101 串为 BB 的二进制表示。

    第三行四个数 a, b, c, da,b,c,d。

    输出格式

    一个数表示答案,对 10000000071000000007 取模。

    样例

    样例输入 1

    10
    1001
    0 0 1 1

    样例输出 1

    1

    数据范围与提示

    子任务一(13pts):B ≤ 2^{20}B220。

    子任务二(15pts):B ≤ 2^{100}B2100。

    子任务三(19pts):B ≤ 2^{1000}B21000。

    子任务四(15pts):A = 1, B = 2^k − 1A=1,B=2k1。

    子任务五(38pts):无特殊限制。

    对于所有的数据,1 ≤ A ≤ B ≤ 2^{100000}, a + b + c + d ≤ 10^51AB2100000,a+b+c+d105。

    来源

    2019年1月雅礼集训
     

    solution
    我们可以用abcd算出区间长,需要多少0(s0),这些0分成几段(n0),需要多少1(s1),这些1分成几段(n1),
    我们先不考虑限制。
    考虑插板法,0的方案为C(s0-1,n0-1)
    方案数C(s0-1,n0-1)*C(s1-1,n1-1)
    有限制的就从第1为开始像数位dp一样记上下界有没有顶满。
    如果都没顶满就直接算。
    这样效率就2n了
    #include<cstdio>
    #include<iostream>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #define maxn 100005
    #define mod 1000000007
    #define ll long long
    using namespace std;
    
    int n,la,lb,a,b,c,d,n0,n1,s0,s1;
    char A[maxn],B[maxn];
    ll h[maxn],ny[maxn],ans;
    ll work(ll a,int num){
        ll ans=1;
        while(num){
            if(num&1)ans=ans*a;
            a=a*a;a%=mod;ans%=mod;num>>=1;
        }
        return ans;
    }
    void pre(){
        n=100000;
        
        h[0]=1;for(int i=1;i<=n;i++)h[i]=h[i-1]*i%mod;
        ny[n]=work(h[n],mod-2);
        for(int i=n-1;i>=0;i--){
            ny[i]=ny[i+1]*(i+1)%mod;
        }
    }
    void Pd(){
        if(n>la){
            A[1]='1';for(int i=2;i<=n;i++)A[i]='0';
        }
        if(n<la){puts("0");exit(0);}
        if(n>lb){puts("0");exit(0);}
        if(n<lb){
            for(int i=1;i<=n;i++)B[i]='1';
        }
    }
    ll C(int N,int M){
        if(N<0||M<0||N<M)return 0;
        return h[N]*ny[M]%mod*ny[N-M]%mod;
    }
    void calc(int n0,int s0,int n1,int s1){
        ll w0=C(s0-1,n0-1),w1=C(s1-1,n1-1);
        if(s0==0&&n0==0)ans+=w1;
        if(s1==0&&n1==0)ans+=w0;
        ans=ans+w0*w1%mod;ans%=mod;
    }
    void solve(int i,int la,bool fa,bool fb,int n0,int s0,int n1,int s1){
        if((n0==0&&s0>0)||(n1==0&&s1>0))return;
        if(i==n+1){
            if(n0==1&&la==0&&!n1&&!s1&&!s0)ans++;
            if(n1==1&&la==1&&!n0&&!s0&&!s1)ans++;
            ans%=mod;
            return;
        }
        if(!fa&&!fb){
            calc(n0,s0,n1,s1);
            if(la==0)calc(n0-1,s0,n1,s1);
            if(la==1)calc(n0,s0,n1-1,s1);
            return;
        }
        
        if(s0<0||n0<0||s1<0||n1<0)return;
        if(i==1)solve(i+1,1,fa,fb,n0,s0,n1,s1-1);
        else {
            
            if(!fa||A[i]=='0'){
                if(la==1)solve(i+1,0,fa,fb&(B[i]=='0'),n0,s0-1,n1-1,s1);
                else solve(i+1,0,fa,fb&(B[i]=='0'),n0,s0-1,n1,s1);
            }
            if(!fb||B[i]=='1'){
                if(la==0)solve(i+1,1,fa&(A[i]=='1'),fb,n0-1,s0,n1,s1-1);
                else solve(i+1,1,fa&(A[i]=='1'),fb,n0,s0,n1,s1-1);
            }
        }
    }
    
    int main()
    {
        pre();
        scanf(" %s",A+1);la=strlen(A+1);
        scanf(" %s",B+1);lb=strlen(B+1);
        
        scanf("%d%d%d%d",&a,&b,&c,&d);
        n=a+b+c+d+1;
        Pd();ans=0;
        if(b==c){
            n0=b;n1=n0+1;
            s0=a+n0,s1=d+n1;
            solve(1,0,1,1,n0,s0,n1,s1);
            printf("%lld
    ",ans);
        }
        else if(b+1==c){
            n0=n1=c;
            s0=a+n0,s1=d+n1;
            solve(1,0,1,1,n0,s0,n1,s1);
            printf("%lld
    ",ans);
        }
        else puts("0");
        return 0;
    }
    View Code
     
  • 相关阅读:
    详解consul的安装和配置
    vs2017
    Android Bitmap 和 ByteArray的互相转换
    android中的byte数组转换(转)
    TensorFlow编译androiddemo
    Linux下命令行安装配置android sdk
    Warning: cast to/from pointer from/to integer of different size
    scribe 搭建遇到的问题
    参数依赖查找(ADL,Argument-dependent lookup)
    模板类继承后找不到父类函数的问题
  • 原文地址:https://www.cnblogs.com/liankewei/p/10604510.html
Copyright © 2011-2022 走看看