[CodePlus2017年12月]可做题2 数论

Description
请你求出满足条件 a1 = i,a2 为区间 [l,r] 中的整数,且 ak mod p = m 的广义
斐波那契数列有多少个。


Sample Input
6
2 17 68 3 23 1
1 17 68 3 57 1
5 17 68 10 11 9
5 17 68 10 71 9
10 17 68 11 12 3
10 17 68 8 6 4


Sample Output
3
1
4
1
5
9


这道题把式子推一下求一下exgcd就好了,没什么好说的。。。


#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;
typedef long long LL;

LL mod;
struct node {
	LL a[2][2];
	node() {memset(a, 0, sizeof(a));}
	friend node operator * (node a, node b) {
		node c;
		for(int i = 0; i < 2; i++) {
			for(int j = 0; j < 2; j++) {
				for(int k = 0; k < 2; k++) {
					(c.a[i][j] += a.a[i][k] * b.a[k][j] % mod) %= mod;
				}
			}
		} return c;
	}
} A, ans;

LL exgcd(LL a, LL b, LL &x, LL &y) {
	if(b == 0) {x = 1, y = 0; return a;}
	else {
		LL tx, ty, d = exgcd(b, a % b, tx, ty);
		x = ty, y = tx - ty * (a / b);
		return d;
	}
}

int main() {
	int tt; scanf("%d", &tt);
	while(tt--) {
		LL X, l, r, k, m;
		scanf("%lld%lld%lld%lld%lld%lld", &X, &l, &r, &k, &mod, &m);
		k -= 3; X %= mod;
		A.a[0][0] = 0; A.a[0][1] = 1;
		A.a[1][0] = 1; A.a[1][1] = 1;
		ans.a[0][0] = 1, ans.a[0][1] = 1;
		ans.a[1][0] = ans.a[1][1] = 0;
		while(k) {
			if(k & 1) ans = ans * A;
			A = A * A; k /= 2;
		} (m -= X * ans.a[0][0] % mod) %= mod;
		(m += mod) %= mod;
		LL x, y, d = exgcd(ans.a[0][1], mod, x, y);
		if(m % d != 0) {printf("0\n"); continue;}
		LL u = mod / d, hh;
		x = (x * (m / d) % u + u) % u;
		if(x >= l && x <= r) {
			x = x - u * ((x - l) / u);
			hh = (r - x) / u + 1;
		} else if(x < l){
			x = x + u * ((l - x + u - 1) / u);
			if(x > r) hh = 0;
			else hh = (r - x) / u + 1;
		} else {
			x = x - u * ((x - l + u - 1) / u);
			if(x < l) hh = 0;
			else hh = (r - x) / u + 1;
		} printf("%lld\n", hh);
	}
	return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值