zoukankan      html  css  js  c++  java
  • BZOJ_2813_奇妙的Fibonacci_线性筛

    BZOJ_2813_奇妙的Fibonacci_线性筛

    Description

    Fibonacci数列是这样一个数列:
    F1 = 1, F2 = 1, F3 = 2 . . .
    Fi = Fi-1 + Fi-2 (当 i >= 3)
    pty忽然对这个古老的数列产生了浓厚的兴趣,他想知道:对于某一个Fibonacci数Fi,
    有多少个Fj能够整除Fi (i可以等于j),他还想知道所有j的平方之和是多少。

    Input

    第一行一个整数Q,表示Q个询问。

    第二行四个整数:Q1, A, B, C

    i个询问Qi = (Qi-1 * A + B) mod C + 1(i >= 2)

    Output

    Ai代表第i个询问有多少个Fj能够整除FQi

    Bi代表第i个询问所有j的平方之和。

    输出包括两行:

    第一行是所有的Ai之和。

    第二行是所有的Bi之和。

    由于答案过大,只需要输出除以1000000007得到的余数即可。

    Sample Input

    2
    2 2 1 8

    Sample Output

    6
    55

    HINT

    对于100%的数据保证:Q <= 3*10^6,C <= 10^7,A <= 10^7,B <= 10^7,1 <= Q1<= C


    结论:(fn,fm)=f(n,m)

    证明直接上图片:

    然后好办了。

    fj|fi

    (fi,fj)=fj

    f(i,j)=fj

    (i,j)=j 或  (i,j)=1且j=2。

    线筛约数的平方之和,后面那个特判即可。

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cstdlib>
    #include <cmath>
    using namespace std;
    typedef long long ll;
    #define mod 1000000007
    #define N 10000050
    #define M 10000000
    int prime[N],cnt,cs[N],ys[N];
    ll pf[N];
    bool vis[N];
    void init() {
        ll i,j; ys[1]=pf[1]=1;
        for(i=2;i<=M;i++) {
            if(!vis[i]) {
                prime[++cnt]=i,cs[i]=i,ys[i]=2,pf[i]=(ll(i)*i+1)%mod;
                for(j=i*i;j<=M;j*=i) {
                    ys[j]=ys[j/i]+1;
                    pf[j]=(pf[j/i]+j*j)%mod;
                }
            }
            for(j=1;j<=cnt&&i*prime[j]<=M;j++) {
                int y=i*prime[j];
                vis[y]=1;
                if(i%prime[j]==0) {
                    cs[y]=cs[i]*prime[j];
                    if(i!=cs[i]) {
                        pf[y]=pf[i/cs[i]]*pf[prime[j]*cs[i]]%mod;
                        ys[y]=ys[i/cs[i]]*ys[prime[j]*cs[i]];
                    }
                    break;
                }
                cs[y]=prime[j];
                pf[y]=pf[i]*pf[prime[j]]%mod;
                ys[y]=ys[i]*ys[prime[j]];
            }
        }
    }
    int main() {
        init();
        ll Q,A,B,C;
        int n;
        ll ans1=0,ans2=0;
        scanf("%d%lld%lld%lld%lld",&n,&Q,&A,&B,&C);
        A%=C; B%=C;
        while(n--) {
            // printf("%d %lld
    ",ys[Q],pf[Q]);
            ans1+=ys[Q]+(Q&1); if(ans1>=mod) ans1-=mod;
            ans2+=pf[Q]+(Q&1)*4; if(ans2>=mod) ans2-=mod;
            Q=(Q*A+B)%C+1;
        }
        printf("%lld
    %lld
    ",ans1,ans2);
    }
    
  • 相关阅读:
    网络兼职轻松赚
    微信H5支付demo
    支付宝H5支付demo
    笔记本安装SSD固态硬盘详细的优化设置
    JQuery的AJAX
    第二次面试
    存储过程的总结
    SQl数据操作和查询
    面对考试毫无畏惧的SSH
    掷骰子-IOS新手项目练习(抱歉,由于个人原因,图片没显示,要源码的项目私聊)
  • 原文地址:https://www.cnblogs.com/suika/p/9462883.html
Copyright © 2011-2022 走看看