#84. Exercise
Exercise
Exercise
题目描述
Farmer John 为奶牛们想出了一套新的晨练方案(又来了)! 和之前一样,Farmer John 的 头奶牛()排成一列站着。从左到右第 头奶牛的编号为 (对所有 )。他让她们重复执行下面的步骤,直到奶牛的顺序回到最开始时的顺序。
给定一个长度为 的排列 ,奶牛改变队形的方式是:变化前从左到右第 头奶牛,在变化后会处在从左到右第 个位置。
例如,如果 ,那么奶牛执行一步后会立刻回到相同的顺序。如果 ,那么奶牛会执行 6 步才回到原始顺序。每一步之后从左到右奶牛的顺序如下: 0 steps: 1 step: 2 steps: 3 steps: 4 steps: 5 steps: 6 steps:
请计算对所有长度为 的 种排列 ,所需步数的乘积。 由于该数可能非常大,请输出答案对 取模的结果(,且 为质数)。
使用 C++ 的选手可能会发现来自 KACTL 的如下代码有帮助。该方法称为 Barrett reduction,它可以让你在 为常数但在编译期未知时,将计算 的速度提升数倍。(遗憾的是,我们不知道 Java 是否有类似优化。) #include <bits/stdc++.h> using namespace std;
typedef unsigned long long ull; typedef __uint128_t L; struct FastMod { ull b, m; FastMod(ull b) : b(b), m(ull((L(1) << 64) / b)) {} ull reduce(ull a) { ull q = (ull)((L(m) * a) >> 64); ull r = a - q * b; // can be proven that 0 <= r < 2*b return r >= b ? r - b : r; } }; FastMod F(2);
int main() { int M = 1000000007; F = FastMod(M); ull x = 10ULL*M+3; cout << x << " " << F.reduce(x) << "\n"; // 10000000073 3 }
输入格式
第一行包含 和 。
输出格式
输出一个整数。
5 1000000007
369329541
提示
对于每个 ,下面数组的第 个元素表示会使奶牛用 步回到原始顺序的排列数量:。 答案为 $1^1\cdot 2^{25}\cdot 3^{20}\cdot 4^{30}\cdot 5^{24}\cdot 6^{20}\equiv 369329541\pmod{10^9+7}$。 Note: 本题的内存限制提升至 512 MB。 SCORING: 测试点 2 满足 。 测试点 3-5 满足 。 测试点 6-8 满足 。 测试点 9-12 满足 。 测试点 13-16 没有额外限制。 题目出题人:Benjamin Qi
标签: USACO|2020|Platinum
来源
USACO|2020|Platinum