• 【BZOJ】3329: Xorequ


    【题意】给定方程x^3x=2x,求<=x和<=2^x的满足方程的正整数个数。

    【算法】数位DP,矩阵快速幂

    【题解】异或相当于不进位加法。

    移项得,x^2x=3x,又因为x+2x=3x,所以x+2x不能产生进位。

    又2x=x<<1,所以x+(x<<1)不进位当且仅当x中不存在相邻的1。

    问题转化为求<=x的二进制不存在相邻1的正整数个数,state记录前一位为0或1,进行简单的数位DP。(递推的话就表示最高位,然后从下一位对应转移)

    第二个问题,设2^x的答案为f[x],最高位为x。若x位为0,则ans=f[x-1]。若x位为1,则x-1位为0,ans=f[x-2]。

    所以,f[x]=f[x-1]+f[x-2],用矩阵快速幂求解斐波那契数列。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define ll long long
    using namespace std;
    const int maxn=100,MOD=1e9+7;
    ll f[maxn][maxn],n,ans[5][5],A[5][5],c[5][5];
    int a[maxn];
    ll dfs(int pos,int state,int limit){
        if(pos==-1)return 1;
        if(!limit&&~f[pos][state])return f[pos][state];
        ll sum=dfs(pos-1,0,limit&&a[pos]==0);
        if((!limit||a[pos]==1)&&state==0)sum+=dfs(pos-1,1,limit);
        if(!limit)f[pos][state]=sum;
        return sum;
    }
    void mul(ll A[5][5],ll B[5][5]){
        for(int i=0;i<2;i++)
            for(int j=0;j<2;j++){
                c[i][j]=0;
                for(int k=0;k<2;k++)
                    c[i][j]=(c[i][j]+B[i][k]*A[k][j])%MOD;
            }
        for(int i=0;i<2;i++)
            for(int j=0;j<2;j++)
                A[i][j]=c[i][j];
    }
    ll ask(ll x){
        ans[0][0]=ans[1][0]=1;ans[0][1]=ans[1][1]=0;
        A[0][0]=A[0][1]=A[1][0]=1;A[1][1]=0;
        while(x){
            if(x&1)mul(ans,A);
            mul(A,A);
            x>>=1;
        }
        return ans[0][0];
    }
    int main(){
        int T;
        scanf("%d",&T);
        memset(f,-1,sizeof(f));
        while(T--){
            scanf("%lld",&n);
            ll num=n;//
            int len=0;
            while(num){
                a[len++]=num%2;
                num/=2;
            }
            printf("%lld
    %lld
    ",dfs(len-1,0,1)-1,ask(n));
        }
        return 0;
    }
    View Code

    注意long long。

  • 相关阅读:
    yes---重复输出指定的字符串
    info---Linux下info格式的帮助指令。
    hostid---打印当前主机的十六进制数字标识
    clear---清除当前屏幕
    whoami---打印当前有效的用户名称
    users---显示当前登录系统的所有用户的用户列表
    md5sum---文件校验和
    mesg---设置当前终端的写权限
    man帮助
    whatis---查询一个命令执行什么功能
  • 原文地址:https://www.cnblogs.com/onioncyc/p/7739318.html
Copyright © 2020-2023  润新知