• BZOJ3329 Xorequ(数位dp+矩阵快速幂)


      显然当x中没有相邻的1时该式成立,看起来这也是必要的。

      于是对于第一问,数位dp即可。第二问写出dp式子后发现就是斐波拉契数列,矩阵快速幂即可。

    #include<iostream> 
    #include<cstdio>
    #include<cmath>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    int read()
    {
        int x=0,f=1;char c=getchar();
        while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
        while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
        return x*f;
    }
    #define P 1000000007
    #define ll long long
    int T,num[100];
    ll n,dp[100][2][2];
    struct matrix
    {
        int n,a[2][2];
        matrix operator *(const matrix&b) const
        {
            matrix c;c.n=n;memset(c.a,0,sizeof(c.a));
            for (register int i=0;i<n;i++)
                for (register int j=0;j<2;j++)
                    for (register int k=0;k<2;k++)
                    c.a[i][j]=(c.a[i][j]+1ll*a[i][k]*b.a[k][j]%P)%P;
            return c;
        }
    }f,a;
    ll solve1(ll n)
    {
        memset(dp,0,sizeof(dp));
        int m=-1;
        while (n) num[++m]=n&1,n>>=1;
        dp[m+1][0][1]=1;
        for (int i=m;~i;i--)
        if (num[i])
        {
            dp[i][0][0]=dp[i+1][0][0]+dp[i+1][0][1]+dp[i+1][1][0]+dp[i+1][1][1];
            dp[i][1][0]=dp[i+1][0][0];
            dp[i][1][1]=dp[i+1][0][1];
        }
        else
        {
            dp[i][0][0]=dp[i+1][0][0]+dp[i+1][1][0];
            dp[i][0][1]=dp[i+1][0][1]+dp[i+1][1][1];
            dp[i][1][0]=dp[i+1][0][0];
        }
        return dp[0][0][0]+dp[0][0][1]+dp[0][1][0]+dp[0][1][1];
    }
    int solve2(ll n)
    {
        a.n=2;a.a[0][0]=0;a.a[0][1]=a.a[1][0]=a.a[1][1]=1;
        f.n=1;f.a[0][0]=0,f.a[0][1]=1;
        for (;n;n>>=1,a=a*a) if (n&1) f=f*a;
        return f.a[0][1];
    }
    int main()
    {
    #ifndef ONLINE_JUDGE
        freopen("bzoj3329.in","r",stdin);
        freopen("bzoj3329.out","w",stdout);
        const char LL[]="%I64d
    ";
    #else
        const char LL[]="%lld
    ";
    #endif
        T=read();
        while (T--)
        {
            scanf(LL,&n);
            printf(LL,solve1(n)-1);
            printf("%d
    ",solve2(n+1));
        }
        return 0;
    }
  • 相关阅读:
    前端面试的一道数组元素值去重问题
    数组元素前移,第一个元素放置数组末位
    Linux 查询oracle错误日志&警告日志
    CentOS 6.4 源码安装MySQL 5.6
    Oracle 表空间不足引起的问题及解决方法
    Oracle 强制中止正在执行的SQL语句
    request for member 'GetByteArrayElements'
    jni入门 eclipsecygwin+ndk
    ffmpeg结构体(二)
    ffmpeg结构体(三)
  • 原文地址:https://www.cnblogs.com/Gloid/p/9685996.html
Copyright © 2020-2023  润新知