zoukankan      html  css  js  c++  java
  • bzoj 4666

    玄学题...

    首先,如果$f_{i}equiv a$ $mod$ $10^{y}$,那么一定有$f_{i}equiv a$ $mod$ $10^{y-1}$

    据此我们可以只找出满足$f_{i}equiv a$ $mod$ $10^{y-1}$的项,然后向上检验即可

    可是这样的项是无穷的啊

    斐波那契数列在模意义下有循环节,且$10^{y}$的循环节长度一定是$10^{y-1}$循环节长度的整数倍

    这样我们按循环节长度枚举就好了

    代码:

    #include <cstdio>
    #include <cmath>
    #include <cstring>
    #include <cstdlib>
    #include <iostream>
    #include <algorithm>
    #include <queue>
    #include <stack>
    #define ll long long 
    using namespace std;
    ll mode,len;
    ll pow_add(ll x,ll y)
    {
        ll ret=0;
        while(y)
        {
            if(y&1)ret=(ret+x)%mode;
            x=(x+x)%mode,y>>=1;
        }
        return ret;
    }
    struct MAT
    {
        ll a[2][2];
        
        friend MAT operator * (MAT x,MAT y)
        {
            MAT ret;
            memset(ret.a,0,sizeof(ret.a));
            for(int i=0;i<=1;i++)for(int j=0;j<=1;j++)for(int k=0;k<=1;k++)ret.a[i][j]=(ret.a[i][j]+pow_add(x.a[i][k],y.a[k][j]))%mode;
            return ret;
        }
        MAT pow_mul(MAT x,ll y)
        {
            MAT ret;
            ret.a[0][0]=ret.a[1][1]=1;
            ret.a[1][0]=ret.a[0][1]=0;
            while(y)
            {
                if(y&1)ret=ret*x;
                x=x*x,y>>=1;
            }
            return ret;
        }
    }f,g,ori,t;
    ll q;
    vector <ll> ans,tempans;
    int main()
    {
        freopen("words.in","r",stdin);
        freopen("words.out","w",stdout);
        scanf("%lld",&q);
        mode=len=1;
        ans.push_back(0);
        ori.a[0][0]=ori.a[1][0]=ori.a[0][1]=1;
        for(int i=1;i<=13;i++)
        {
            mode*=10;
            f=f.pow_mul(ori,0),g=g.pow_mul(ori,len);
            ll templen=0;
            do{
                for(int j=0;j<ans.size();j++)
                {
                    if(t.pow_mul(ori,ans[j]+templen).a[0][1]==q%mode)tempans.push_back(ans[j]+templen);
                }
                f=f*g,templen+=len;
            }while(f.a[0][0]!=1||f.a[1][0]!=0||f.a[0][1]!=0|f.a[1][1]!=1);
            ans=tempans,tempans.clear(),len=templen;
        }
        if(ans.empty())printf("-1
    ");
        else printf("%lld
    ",ans[0]);
        return 0;
    }
  • 相关阅读:
    [leetcode]存在重复
    [leetcode]旋转数组
    git使用方法(持续更新)
    [LeetCode]从排序数组中删除重复项
    Communications link failure--分析之(JDBC的多种超时情况)
    云主机挂载磁盘
    hadoop对于压缩文件的支持
    linux 转移mysql文件操作流程
    MindManager2018 修改过期时间 配置文件路径
    Innodb 中 RR 隔离级别能否防止幻读?
  • 原文地址:https://www.cnblogs.com/zhangleo/p/11059639.html
Copyright © 2011-2022 走看看