zoukankan      html  css  js  c++  java
  • [BZOJ3329] Xorequ

    [BZOJ3329] Xorequ

    Description

    Input

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

    Output

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

    Sample Input

    1
    1

    Sample Output

    1
    2

    HINT

    x=1与x=2都是原方程的根,注意第一个问题的解不要mod 10^9+7
    1<=N<=10^18
    1<=T<=1000

    试题分析

    由于我们有式子(xoplus 3x = 2x),可以尝试进行推导。
    由于(xoplus x = 0)(0 oplus x = 0),可推导出:$$xoplus 2x = 3x$$
    3x就相当于是x的二进制位上的所有1前面再加一个1,然后再考虑进位。
    (xoplus 2x = 3x),由于(2x)(x)右移一位,相当于效果与(3x)相同。
    因此可以证明没有进位,也就是说一个数没有1的位相邻。
    对于第二问,打一个表推推式子矩阵快速幂一下。

    强行二合一

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<vector>
    #include<algorithm>
     
    using namespace std;
    #define LL long long
     
    inline LL read(){
        LL x=0,f=1; char c=getchar();
        for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
        for(;isdigit(c);c=getchar()) x=x*10+c-'0';
        return x*f;
    }
    const LL MAXN = 1000010;
    const LL INF = 2147483600;
    const LL Mod = 1e9+7;
     
    LL N,K,M,P,TT;
    LL a[101][101],b[101][101],c[101][101];
     
    void Mul1(){
        memset(b,0,sizeof(b));
        for(LL i=1;i<=N;i++)
            for(LL j=1;j<=M;j++)
                for(LL k=1;k<=K;k++)
                    b[i][j]+=a[i][k]*c[k][j]%Mod,b[i][j]%=Mod;
        for(LL i=1;i<=N;i++){
            c[i][1]=b[i][1];
        }
        return ;
    }
    void Mul2(){
        memset(b,0,sizeof(b));
        for(LL i=1;i<=N;i++)
            for(LL j=1;j<=N;j++)
                for(LL k=1;k<=N;k++)
                    b[i][j]+=a[i][k]*a[k][j]%Mod,b[i][j]%=Mod;
        for(LL i=1;i<=N;i++){
            for(LL j=1;j<=N;j++)
                a[i][j]=b[i][j];
        }
        return ;
    }
    LL dp[67][2][2]; LL str[MAXN+1];LL cnt=0;
    inline void split(LL x){
        while(x){
            str[++cnt]=(x&1);
            x=x>>1;
        } while(cnt<=64) str[++cnt]=0;
        //for(LL i=1;i<=cnt/2;i++) swap(str[i],str[cnt-i+1]);
        //for(int i=cnt;i>=1;i--) cout<<str[i]; cout<<endl;
    }
    LL ans;
     
    int main(){
        //freopen(".in","r",stdin);
        //freopen(".out","w",stdout);
        int T=read(); dp[0][0][0]=1;
        for(LL i=0;i<65;i++){
            for(LL j=0;j<2;j++){
                for(LL k=0;k<2;k++){
                    //cout<<dp[i][j][k]<<":"<<i<<" "<<j<<" "<<k<<endl;
                    if(j==1&&k==1) continue;
                    dp[i+1][0][j]+=dp[i][j][k];
                    if(!j) dp[i+1][1][j]+=dp[i][j][k];
                }
            }
        } 
        while(T--){
            P=TT=read(); 
            memset(a,0,sizeof(a));
            memset(b,0,sizeof(b));
            memset(c,0,sizeof(c));
            N=2; M=1; K=2;
            a[1][1]=a[1][2]=1; a[2][1]=1;
            c[1][1]=1; c[2][1]=1; ++P;
            while(P){
                if(P&1) Mul1(); P>>=1;
                Mul2();
            } N=TT; cnt=0;
            split(N); ans=0;
            for(LL i=cnt;i>=2;i--){
                if(str[i]==1)
                    ans+=dp[i][0][0]+dp[i][0][1];
                if(str[i-1]==str[i]&&str[i-1]==1) {ans+=dp[i][1][0]; break;}
                if(i==2){++ans; ans+=str[i-1]; }
            } 
            if(N!=1) printf("%lld
    ",ans-1);
            else printf("%lld
    ",1LL);
            printf("%lld
    ",c[2][1]%Mod);
        }
        return 0;
         
    }
    
  • 相关阅读:
    搜索回车跳转页面
    登录验证码
    【排序算法】排序算法之插入排序
    PAT 乙级 1044 火星数字 (20 分)
    PAT 甲级 1035 Password (20 分)
    PAT 甲级 1041 Be Unique (20 分)
    PAT 甲级 1054 The Dominant Color (20 分)
    PAT 甲级 1027 Colors in Mars (20 分)
    PAT 甲级 1083 List Grades (25 分)
    PAT 甲级 1005 Spell It Right (20 分)
  • 原文地址:https://www.cnblogs.com/wxjor/p/9521646.html
Copyright © 2011-2022 走看看