BZOJ 3288
-
题目
-
分析
题目比较神奇,首先要知道求矩阵行列式的值是可以进行行列式变换,变换成阶梯矩阵,则最后的答案是
∣ A ∣ = ∏ i = 1 n a i i |A| = \prod_{i = 1}^{n}a_{ii} ∣A∣=∏i=1naii
我们计算 n = 1 ∼ 10 n = 1 \sim 10 n=1∼10 的行列式的值。(运用行列式变换的方法)
可以得到对角上的 a i i a_{ii} aii 的值是: 1 , 1 , 2 , 2 , 4 , 2 , 6 , 4 , 6.. 1 ,1 ,2,2,4,2,6,4,6 .. 1,1,2,2,4,2,6,4,6.. 惊喜的发现这就是 φ ( i ) \varphi(i) φ(i) 啊,所以最终的答案:
∏ i = 1 n φ ( i ) \prod_{i = 1}^{n}\varphi(i) ∏i=1nφ(i)
-
代码
const int MAX_N = 1e6 + 6; int v[MAX_N], prime[MAX_N], phi[MAX_N]; const int mod = 1000000007; int m; void euler(int n) { memset(v, 0, sizeof(v)); m = 0; phi[1] = 1; for (int i = 2; i <= n; i++) { if (v[i] == 0) { v[i] = i, prime[++m] = i; phi[i] = i - 1; } for (int j = 1; j <= m; j++) { if (prime[j] > v[i] || prime[j] > n / i) break; v[i * prime[j]] = prime[j]; phi[i * prime[j]] = phi[i] * (i % prime[j] ? prime[j] - 1 : prime[j]); } } } int main () { //freopen("input.in", "r", stdin); //freopen("test.out", "w", stdout); int n; read(n); euler(n); ll ans = 1; for (int i = 1; i <= n; i++) { ans = ans * phi[i] % mod; ans %= mod; } printf("%lld\n", ans);
-
题型
欧拉函数线性筛