【省选模拟】Fibonacci (线性筛)

在这里插入图片描述

  • 一个需要知道的结论是 g c d ( f i b n , f i b m ) = f i b g c d ( n , m ) gcd(fib_n,fib_m)=fib_{gcd(n,m)} gcd(fibn,fibm)=fibgcd(n,m),比较容易证明
    于是 f i b m ∣ f i b n ⇒ m ∣ n fib_m|fib_n\Rightarrow m|n fibmfibnmn,所以题目就是求 σ 0 ( n ) , σ 2 ( n ) \sigma_0(n),\sigma_2(n) σ0(n),σ2(n) 的前缀和
    线筛一波,要特判 2 2 2 的情况因为 f i b 2 = 1 fib_2=1 fib2=1,有些头凸
#include<bits/stdc++.h>
#define cs const
using namespace std;
typedef long long ll;
int read(){
	int cnt = 0, f = 1; char ch = 0;
	while(!isdigit(ch)){ ch = getchar(); if(ch == '-') f = -1; }
	while(isdigit(ch)) cnt = cnt*10 + (ch-'0'), ch = getchar();
	return cnt * f;
}
cs int Mod = 1e9 + 7;
int add(int a, int b){ return a + b >= Mod ? a + b - Mod : a + b; }
int mul(int a, int b){ return 1ll * a * b % Mod; }
int dec(int a, int b){ return a - b < 0 ? a - b + Mod : a - b; }
void Add(int &a, int b){ a = add(a, b); }
void Mul(int &a, int b){ a = mul(a, b); }
int sqr(int a){ return mul(a, a); }
cs int N = 1e7 + 50;
int Q, x, A, B, C, Sa, Sb;
int sig[N], sig2[N], mnp[N], vl[N], vl2[N], pc; 
bool isp[N]; int prim[N/5];
void prework(int n){
	sig[1] = sig2[1] = 1;
	for(int i = 2; i <= n; i++){
		if(!isp[i]){
			prim[++pc] = i, 
			vl[i] = sig[i] = 2;
			vl2[i] = sig2[i] = add(sqr(i),1);
			mnp[i] = 1;
		}
		for(int j = 1; j <= pc; j++){
			if(prim[j] * i > n) break;
			int nx = prim[j] * i; isp[nx] = 1;
			if(i % prim[j] == 0){
				mnp[nx] = mnp[i];
				vl[nx] = add(vl[i],1);
				vl2[nx] = add(mul(sqr(prim[j]),vl2[i]),1);
				sig[nx] = mul(sig[mnp[nx]],vl[nx]);
				sig2[nx] = mul(sig2[mnp[nx]],vl2[nx]); 
				break;
			} 
			mnp[nx] = i; 
			vl[nx] = 2; 
			vl2[nx] = add(sqr(prim[j]),1);
			sig[nx] = mul(sig[i],sig[prim[j]]);
			sig2[nx] = mul(sig2[i],sig2[prim[j]]);
		}
	}
}
int main(){
	Q = read();
	x = read(), A = read(), B = read(), C = read();
	prework(C+1);
	while(Q--){
		if(x & 1) Add(Sa, 1), Add(Sb, 4);
		Add(Sa, sig[x]);
		Add(Sb, sig2[x]);
		x = ((ll)x * A + B) % C + 1;
	} cout << Sa << '\n' << Sb; 
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

FSYo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值