BZOJ 3288 Mato矩阵 解题报告

这个题好神呀。。Orz taorunz

有一个结论,这个结论感觉很优美:

$$ans = \prod_{i=1}^{n}\varphi(i)$$

至于为什么呢,大概是这样子的:

对于每个数字 $x$,第 $x$ 行有 $x - \varphi(x)$ 个数字不为 $1$,则说明这一行要被消 $x - \varphi(x)$ 次(别忘了每一行都会被 $1$ 给消一次),每次消元都会令 $A[x][x]$ 减一,所以 $A[x][x]$ 最后会变成 $\varphi(x)$,所以答案就是这个啦。

时间空间复杂度均为 $O(n)$。

 1 #include <cstdio>
 2 typedef long long LL;
 3 #define N 1000000 + 5
 4 #define M 100000 + 5
 5 #define Mod 1000000007
 6
 7 int n, ans = 1, Phi[N], q[M];
 8
 9 int main()
10 {
11     scanf("%d", &n);
12     for (int i = 2; i <= n; i ++)
13     {
14         if (!Phi[i])
15         {
16             Phi[i] = i - 1;
17             q[++ q[0]] = i;
18         }
19         for (int j = 1; j <= q[0] && i * q[j] <= n; j ++)
20         {
21             if (i % q[j] == 0)
22             {
23                 Phi[i * q[j]] = Phi[i] * q[j];
24                 break ;
25             }
26             Phi[i * q[j]] = Phi[i] * Phi[q[j]];
27         }
28         ans = (LL) ans * Phi[i] % Mod;
29     }
30     printf("%d\n", ans);
31     return 0;
32 }

3288_Gromah

时间: 2024-10-19 18:45:24

BZOJ 3288 Mato矩阵 解题报告的相关文章

BZOJ 3288: Mato矩阵

Description 一个 \(n*n\) 行列式,\((i,j)=gcd(i,j)\) Sol 线性筛. 这道题神奇的筛出来 \(phi\) ... 打表可以发现,一个数会被他所有的因子减掉因子的 \(phi\) ... 然后我就不会证明了... Code /************************************************************** Problem: 3288 User: BeiYu Language: C++ Result: Accepte

BZOJ 3288 Mato矩阵 线性筛

题目大意:一个M*M的矩阵,(i,j)位置上的值是gcd(i,j),问这个矩阵的行列式的值. 思路:考试的时候考了这个题,有人居然打表发现规律,简直跪啊... 其实用高斯消元之后不难发现,要求的就是从1到m的phi的乘积,一个线性筛就解决了. CODE: #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define MAX 1000010 #defi

BZOJ 1044 木棍分割 解题报告(二分+DP)

来到机房刷了一道水(bian’tai)题.题目思想非常简单易懂(我的做法实际上参考了Evensgn 范学长,在此多谢范学长了) 题目摆上: 1044: [HAOI2008]木棍分割 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 3162  Solved: 1182[Submit][Status][Discuss] Description 有n根木棍, 第i根木棍的长度为Li,n根木棍依次连结了一起, 总共有n-1个连接处. 现在允许你最多砍断m个

BZOJ 4341 [CF253 Printer] 解题报告

乍一看这个题好像可以二分优先度搞搞... 实际上能不能这么搞呢...? 我反正不会... 于是开始讲我的乱搞算法: 首先肯定要把任务按照优先度排序. 用一棵在线建点的线段树维护一个时刻是否在工作. 然后就依次插入任务,记为 i,具体而言就是二分其右端点,然后令这整个区间都变成 “工作” 的状态. 在 i 被插入之前,还要检验一下在当前情况那个神秘任务的右端点是不是题中所要求的那个. 如果是,并且 i-1 的优先度和 i 的优先度不相邻或者 i 就是最优先的任务,那么就令那个神秘任务的优先度为 i

BZOJ 3983 Takeover Wars 解题报告

我猜了一个结论,能合并就合并,到了必须要敌对交易的时候才进行敌对交易. 然后合并的话,肯定是拿最大的两个去合并. 至于敌对交易,肯定是干掉对方最大的公司才是有意义的. 于是各种分类讨论...看代码好了... #include <cmath> #include <queue> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> usi

BZOJ 4123 [Baltic2015] Hacker 解题报告

首先,Alice 会选择一个长度为 $\lfloor\frac{n+1}{2}\rfloor$ 的区间,我们把这个长度记为 $len$. 有这么一个结论:令 $F_i$ 为覆盖 $i$ 点的所有长度为 $len$ 的区间的元素和的最小值,那么答案就是 $F_i$ 的最大值. 因为 Bob 可以控制 Alice 最后选择的是什么区间. [扯淡 ing]大概是这样子: 假设 Alice 一开始选择的是红色的点 $i$,并且蓝色的线以左所覆盖的区间和就是 $F_i$,那么对于 Bob,他就可以选择绿色

BZOJ 3969 Low Power 解题报告

我们首先将所有电池排序,那么我们可以找到一组最优方案,使得一台机器的能量之差是相邻两电池的能量之差. 然后我们就二分这个答案,从前往后贪心地选这个数对,然后看是否所有的数对都是满足条件的. 假设这个数对是 i - 1, i,并且是第 j 个数对,那么我们称满足条件为: 2nk - i + 2 >= 2k(n - j + 1) 意思就是能拿出足够多的电池来组成机器人. 然后注意特判:如果不能选出足够多的数对就返回 false,我在这里 WA 到死... 毕竟 Gromah 太弱,只会做水题. 1

【技术向】NOIP2014第三题螺旋矩阵解题报告

BZOJ 3971 Матрёшка 解题报告

很自然想到区间 DP. 设 $Dp[i][j]$ 表示把区间 $[i, j]$ 内的套娃合并成一个所需要的代价,那么有: $Dp[i][i] = 0$ $Dp[i][j] = min\{Dp[i][k] + Dp[k + 1][j] + Merge([i, k], [k + 1, j])\} (i \le k < j)$ 于是问题在于算 $Merge([a, b], [c, d])$. 我们考虑一下:区间 $[a, b]$ 内的哪些套娃是需要打开的: 是不是 $[a, b]$ 中所有大于 $[c