ZOJ 3707 Calculate Prime S
2016-04-12 23:31
417 查看
Description
Define S
as the number of subsets of {1, 2, ..., n} that contain no consecutive integers. For each S
, if for all i (1 ≤ i < n) gcd(S[i],S
) is 1, we call that S
as
a Prime S. Additionally, S[1] is also a Prime S. For the Kth minimum Prime S, we'd like to find the minimum S
which is multiple of X and not less than the Kth minimum Prime
S. Please tell us the corresponding (S
÷ X) mod M.
Input
There are multiple test cases. The first line of input is an integer T indicating the number of test cases.
For each test case, there are 3 integers K (1 ≤ K ≤ 106), X (3 ≤ X ≤ 100) and M (10 ≤ M ≤ 106), which are defined in above description.
Output
For each test case, please output the corresponding (S
÷ X) mod M.
Sample Input
Sample Output
1
数论题,没办法,本人数论比较渣,看人家题解搞懂的。
首先可以根据题目知道要找的数一定是斐波那契数,
然后,要知道斐波那契数的gcd是有结论的,详情点击。
然后剩下的就是矩阵乘法和余数的问题,余数这里同样有个巧妙的办法
x/y%z=x%(y*z)/y所以稍微转换一下就好了。
Define S
as the number of subsets of {1, 2, ..., n} that contain no consecutive integers. For each S
, if for all i (1 ≤ i < n) gcd(S[i],S
) is 1, we call that S
as
a Prime S. Additionally, S[1] is also a Prime S. For the Kth minimum Prime S, we'd like to find the minimum S
which is multiple of X and not less than the Kth minimum Prime
S. Please tell us the corresponding (S
÷ X) mod M.
Input
There are multiple test cases. The first line of input is an integer T indicating the number of test cases.
For each test case, there are 3 integers K (1 ≤ K ≤ 106), X (3 ≤ X ≤ 100) and M (10 ≤ M ≤ 106), which are defined in above description.
Output
For each test case, please output the corresponding (S
÷ X) mod M.
Sample Input
1 1 3 10
Sample Output
1
数论题,没办法,本人数论比较渣,看人家题解搞懂的。
首先可以根据题目知道要找的数一定是斐波那契数,
然后,要知道斐波那契数的gcd是有结论的,详情点击。
然后剩下的就是矩阵乘法和余数的问题,余数这里同样有个巧妙的办法
x/y%z=x%(y*z)/y所以稍微转换一下就好了。
#include<map> #include<set> #include<cmath> #include<queue> #include<stack> #include<bitset> #include<cstdio> #include<string> #include<cstring> #include<algorithm> #include<functional> using namespace std; typedef long long LL; const int low(int x) { return x&-x; } const int INF = 0x7FFFFFFF; const int mod = 1e9 + 7; const int maxn = 2e7 + 10; int T, n, m, x; int p[maxn], f[maxn], tot; struct martix { int a[2][2]; }a, b; martix operator *(const martix &a, const martix &b) { martix c; for (int i = 0; i < 2; i++) { for (int j = 0; j < 2; j++) { c.a[i][j] = 0; for (int k = 0; k < 2; k++) { (c.a[i][j] += (LL)a.a[i][k] * b.a[k][j] % m) %= m; } } } return c; } void init() { p[tot++] = 4; for (int i = 2; i < maxn; i++) { if (!f[i]) p[tot++] = i; for (int j = 1; j < tot&&p[j] * i < maxn; j++) { f[p[j] * i] = 1; if (i%p[j] == 0) break; } if (tot > 1e6) break; } for (int i = 0; i < 2; i++) swap(p[i], p[i + 1]); } martix get(martix x, int y) { martix c; c.a[0][0] = c.a[1][1] = 1; c.a[0][1] = c.a[1][0] = 0; for (; y; y >>= 1) { if (y & 1) c = c*x; x = x*x; } return c; } int main() { init(); scanf("%d", &T); while (T--) { scanf("%d%d%d", &n, &x, &m); m *= x; a.a[0][0] = 1; a.a[0][1] = 1; b.a[0][0] = 0; b.a[0][1] = 1; b.a[1][0] = 1; b.a[1][1] = 1; a = a*get(b, p - 2); while (a.a[0][1] % x) { int y = a.a[0][0]; a.a[0][0] = a.a[0][1]; a.a[0][1] = (y + a.a[0][0]) % m; } printf("%d\n", a.a[0][1] / x); } return 0; }
相关文章推荐
- zoj3549 快速幂
- ZOJ 1002
- ZOJ-3861 DFS+回溯
- ZOJ3279 —— 8G island
- zoj_1004-Anagrams by stack
- zoj_2278-Fight for Food
- ZOJ 1001 A+B Problem
- zoj 2710 Two Pipelines
- zoj 386 4000 1 Valid Pattern Lock
- ZOJ 3755 Mines 回溯+剪枝
- ZOJ3750 Dot Dot Dot 枚举状态+BFS
- poj 1514&zoj 1185 Metal Cutting(半平面交)
- ZOJ1101-Gamblers 终于AC。。。
- zoj 1148 The Game 一个晚上终于AC!
- zoj 3420 纯bfs
- PAT 01-复杂度2. Maximum Subsequence Sum (25)&&PAT 01-复杂度1. 最大子列和问题(20)
- 狗狗40题~ (Volume A)
- 狗狗40题~ (Volume B)
- 狗狗40题~ (Volume C)
- ZOJ3319 DP 通过入度出度判非法情况