zoukankan      html  css  js  c++  java
  • BZOJ3329 : Xorequ

    第一问:

    打表可得规律:当且仅当x&(x<<1)=0时才会是解,于是数位DP

    f[i][j][k]表示二进制中前i位,上一位是j,前i位是否等于n的方案数

    第二问:

    打表可得规律:答案为斐波那契数列第n+2项,矩阵快速幂即可

    #include<cstdio>
    typedef long long ll;
    struct mat{
      ll a[2][2];
      mat(){a[0][0]=a[0][1]=a[1][0]=a[1][1]=0;}
      mat operator*(mat b){
        mat c;
        for(int i=0,j,k;i<2;i++)for(j=0;j<2;j++)for(k=0;k<2;k++)(c.a[i][j]+=a[i][k]*b.a[k][j])%=1000000007;
        return c;
      }
    }A,B,C;
    int T,a[65],len,i,j,t;ll n,x,tmp,f[65][2][2];
    int main(){
      scanf("%d",&T);
      while(T--){
        scanf("%lld",&x);
        for(len=0,tmp=x;tmp;a[++len]=tmp&1LL,tmp>>=1LL);
        for(i=1,j=len;i<=len&&i<j;i++,j--)t=a[i],a[i]=a[j],a[j]=t;
        for(i=1;i<=len;i++)f[i][0][0]=f[i][1][0]=f[i][0][1]=f[i][1][1]=0;
        for(i=0;i<=1;i++)f[1][i][i==a[1]]=1;
        for(i=1;i<len;i++){
          if(f[i][0][0])for(j=0;j<=1;j++)f[i+1][j][0]+=f[i][0][0];
          if(f[i][1][0])for(j=0;j<=0;j++)f[i+1][j][0]+=f[i][1][0];
          if(f[i][0][1])for(j=0;j<=a[i+1];j++)f[i+1][j][j==a[i+1]]+=f[i][0][1];
          if(f[i][1][1])for(j=0;j<=0;j++)f[i+1][j][j==a[i+1]]+=f[i][1][1];
        }
        printf("%lld
    ",f[len][0][0]+f[len][1][0]+f[len][0][1]+f[len][1][1]-1);
        for(A=B=C=mat(),A.a[0][1]=A.a[1][0]=A.a[1][1]=B.a[0][0]=C.a[0][0]=C.a[1][1]=1,B.a[1][0]=2;x;x>>=1LL,A=A*A)if(x&1LL)C=C*A;
        C=C*B;
        printf("%lld
    ",C.a[0][0]);
      }
      return 0;
    }
    

      

  • 相关阅读:
    oracle 监听静态注册举例解析
    oracle监听动态注册与静态注册
    oracle startup mount nomount 区别
    RAC的时间同步问题
    RAC环境TNS-12541报错处理
    Oracle参数修改是否需要重启等
    面试提纲
    Dubbo是什么
    为什么要用dubbo,dubbo和zookeeper关系
    Java的参数传递是「按值传递」还是「按引用传递」?
  • 原文地址:https://www.cnblogs.com/clrs97/p/4403185.html
Copyright © 2011-2022 走看看