• Sherlock and the Encrypted Data


    题意:

    对于16进制数字num,假定 $p_0,p_1,...,p_m$ 在该数字中出现过,如果有 $x = 2^{p_0} + 2^{p_1} + ... + 2^{p_m}$

    且 $x oplus num < num$ 则认为 $F(num) = 1$, 不然 $F(num) = 0$

    求$sum_{i=L}^R {F(i)}$

    解法:

    考虑 $F(num) = 1$ 的条件,注意到如果有 $x oplus num < num$,相当于 $num$ 二进制的 $p_m$ 位为1。

    这样考虑数位dp。

    对于确定位,我们记一下最大值。

    对于不确定位,我们枚举一下全局最大值 $p_m$,然后枚举一下 $p_m / 4 +1$ 位可以的16进制的值,然后快速幂+容斥算一下即可。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    
    #define LL long long
    #define N 110
    #define bit(t) (1<<(t))
    
    using namespace std;
    
    int q,num[N],dig[N];
    
    LL qpow(LL x,int n)
    {
        LL ans=1;
        for(;n;n>>=1,x=x*x) if(n&1) ans=ans*x;
        return ans;
    }
    
    LL calc(int m,int tot,int maxnow)
    {
        LL ans=0;
        for(int t=15;t>=maxnow;t--)
        {
            int x = t/4+1;
            int tmp = t%4;
            if(x > tot) continue;
            for(int S=0;S<(1<<3);S++)
            {
                int now=bit(tmp);
                for(int i=0;i<3;i++)
                    if(bit(i)&S) now|=bit((tmp+i+1)%4);
                if(now > t || (dig[x]!=-1 && dig[x]!=now)) continue;
                int cnt=m;
                if(dig[x]==-1) cnt--;
                if(now == t || maxnow == t) ans += qpow(t+1, cnt);
                else ans += qpow(t+1, cnt) - qpow(t, cnt);
            }
        }
        return ans;
    }
    
    LL calc(char *S,bool inc)
    {
        memset(num,0,sizeof(num));
        int tot=strlen(S);
        for(int i=0;i<tot;i++)
        {
            if(S[i]<='9' && S[i]>='0') num[tot-i] = S[i]-'0';
            else num[tot-i] = S[i]-'a'+10;
        }
        if(inc)
        {
            num[1]++;
            for(int i=1;i<=tot;i++)
                if(num[i]>=16) num[i]-=16,num[i+1]++;
            if(num[tot+1]) tot++;
        }
        for(int i=1;i<=tot;i++) dig[i]=-1;
        LL ans = 0;
        int maxnow=0;
        for(int i=tot;i>=1;i--)
        {
            for(int j=0;j<num[i];j++)
                dig[i]=j, ans += calc(i-1, tot, max(maxnow,j));
            dig[i]=num[i];
            maxnow=max(maxnow,dig[i]);
        }
        return ans;
    }
    
    char L[N],R[N];
    
    int main()
    {
        int q;
        cin>>q;
        while(q--)
        {
            cin>>L>>R;
            cout<<calc(R,1)-calc(L,0)<<endl;
        }
        return 0;
    }
    View Code
  • 相关阅读:
    聊天机器人遇到的难题
    Node.js应用程序一起使用Webpack的4个简单步骤
    AngularJS页面渲染完成之后执行DOM操作
    js实现取出数组中的最大数和最小数
    npm安装angular-ui-bootstrap和bower安装
    centos7离线安装nginx
    配置SSH免密登录,总是需要输入密码
    idea win 常用快捷键
    二、centos7在线搭建ceph之Filesystem
    k8s使用cephfs来挂载mysql数据
  • 原文地址:https://www.cnblogs.com/lawyer/p/6841820.html
Copyright © 2020-2023  润新知