zoukankan      html  css  js  c++  java
  • bzoj3329 Xorequ

    Description

    Input

    第一行一个正整数,表示数据组数据 ,接下来T行 每行一个正整数N

    Output

    2*T行 第2*i-1行表示第i个数据中问题一的解,

    第2*i行表示第i个数据中问题二的解,

    x xor 3x == 2x

    可化为x xor 2x == 3x

    由a+b == (a xor b)+(a and b)<<1,得

    x and 2x == 0

    所以x的二进制表示中没有相邻的1

    第一问数位dp即可

    第二问状态转移方程为f[i]=f[i-1]+f[i-2],可用矩阵快速幂优化

    #include<cstdio>
    #define P 1000000007
    typedef long long lint;
    int t;
    lint x;
    lint fs[64]={1,2};
    lint ps[64][2][2]={0,1,1,1};
    void f(lint x){
        lint ans=0;
        for(lint i=61;i>=0;i--){
            if(x>>i&1){
                if(x>>i+1&1){
                    ans+=fs[i]-1;
                    break;
                }else ans+=fs[i];
            }
        }
        lint m[2][2]={0,1,1,1},m1[2][2]={0,0,0,0};
        for(lint i=0;i<62;i++){
            if(x>>i&1){
                for(int a=0;a<2;a++)
                for(int b=0;b<2;b++)
                for(int c=0;c<2;c++){
                    m1[a][b]+=m[a][c]*ps[i][c][b];
                    m1[a][b]%=P;
                }
            for(int a=0;a<2;a++)
            for(int b=0;b<2;b++)
                m[a][b]=m1[a][b],m1[a][b]=0;
            }
        }
        printf("%lld
    %lld
    ",ans,m[1][1]);
    }
    int main(){
        for(int i=2;i<64;i++)fs[i]=fs[i-1]+fs[i-2];
        for(int i=1;i<64;i++){
            for(int a=0;a<2;a++)
            for(int b=0;b<2;b++)
            for(int c=0;c<2;c++){
                ps[i][a][b]+=ps[i-1][a][c]*ps[i-1][c][b];
                ps[i][a][b]%=P;
            }
        }
        scanf("%d",&t);
        while(t--){
            scanf("%lld",&x);
            f(x);
        }
        return 0;
    }
  • 相关阅读:
    poj1087最大流拆点
    3月15上午的函数练习
    3月15
    3月13上午
    3月13
    3月12
    break语句
    3月11
    3月10号
    3月9号
  • 原文地址:https://www.cnblogs.com/ccz181078/p/5191635.html
Copyright © 2011-2022 走看看