奥妙重重的Fibonacci数列

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

题解:

预备知识:
Gcd(Fi,Fj)=FGcd(i,j)
这样的话整个询问就和Fibonacci无关,只需要考虑一个数有多少个约数,所有约数的平方和是多少就好了。

然后设g[i]为<=i的约数平方和,w[i]表示<=i的约数的个数。
<然后我想了想发现它是积性函数。
用线性筛随便搞搞就完了。

然后发现并不是很对,因为当i = 3的时候, Fib2=1 ,过不了这个数据。
我们发现当i为奇数的时候,需要把因数个数+1,平方和+4。
然后就没有了QAQ
<贾老师:简单的题博客就写短一点。
<然而这应该不是简单题吧……这题我考场忘了预备知识就挂了啊QAQ

#include <cstdio>
#include <cstring>
#define Rep(i,n) for(int i = 1;i <= n;i ++)
#define RepG(i,x) for(int i = head[x];~ i;i = edge[i].next)
#define v edge[i].to
using namespace std;
const int N = 10000005;
int p[N],cnt = 0,e[N],q[N];
bool no[N];
long long g[N],w[N];
long long Power(long long a,int p)
{
    long long ans = 1;
    while(p)
    {
        if(p & 1)ans = ans * a;
        p >>= 1;
        a *= a;
    }
    return ans;
}
void Get()
{
    g[1] = w[1] = 1;
    for(int i = 2;i <= 10000000;i ++)
    {
        if(!no[i])p[++ cnt] = i,g[i] = (1ll * i * i + 1) % 1000000007,w[i] = 2,e[i] = 1;
        for(int j = 1;j <= cnt && i * p[j] <= 10000000;j ++)
        {
            no[p[j] * i] = 1;
            if(i % p[j] == 0)
            {
                e[i * p[j]] = e[i] + 1;
                g[p[j] * i] = ((1ll * g[i] * p[j] * p[j]) % 1000000007 + g[i / (1ll * Power(p[j],e[i]))]) % 1000000007;
                w[p[j] * i] = 1ll * w[i] * (e[i] + 2) / (1ll * e[i] + 1);
                break;
            }
            else 
            {
                e[p[j] * i] = 1;
                g[p[j] * i] = (1ll * g[p[j]] * g[i]) % 1000000007;
                w[p[j] * i] = 1ll * w[i] * w[p[j]];
            }
        }
    }
}
long long f[80];
int main ()
{
// freopen("Fibonacci.in","r",stdin);
// freopen("Fibonacci.out","w",stdout);
    f[1] = 1,f[2] = 1;
    for(int i = 3;i <= 75;i ++)f[i] = f[i - 1] + f[i - 2];
    long long Q,A,B,C;
    scanf("%lld",&Q);
    scanf("%d%lld%lld%lld",&q[1],&A,&B,&C);
    /*if(C <= 75){ for(int i = 2;i <= Q;i ++)q[i] = (1ll * q[i - 1] * A + B ) % C + 1; long long a1 = 0,a2 = 0; Rep(i,Q) Rep(j,q[i]) if(f[q[i]] % f[j] == 0)a1 ++,a2 = (a2 + j * j) % 1000000007; a1 %= 1000000007; printf("%lld\n%lld\n",a1,a2); } else */
    {
        long long ans1 = 0,ans2 = 0,ls = 0;
        Get();
        Rep(i,Q)
        {
            long long Now = (ls * A + B) % C + 1;
            if(i == 1)
            {
                Now = q[1];
                if(Now & 1)ans1 ++,ans2 += 4;
                ans1 += w[Now];
                ans1 %= 1000000007;
                ans2 += g[Now];
                ans2 %= 1000000007;
                ls = Now;
            }
            else 
            {
                if(Now & 1)ans1 ++,ans2 += 4;
                ans1 += w[Now];
                ans1 %= 1000000007;
                ans2 += g[Now];
                ans2 %= 1000000007;
                ls = Now;
            }
        }
        printf("%lld\n%lld\n",ans1,ans2);
    }
    return 0;
}

你可能感兴趣的:(奥妙重重的Fibonacci数列)