题目地址

题目链接

题解

注,下方\((i,j)\)均指\(gcd(i,j)\),以及证明过程有一定的跳步,请确保自己会莫比乌斯反演的基本套路。

介绍本题的\(O(n)\)和\(O(n\sqrt{n})\)做法,本题还有\(O(nlogn)\)做法,需要用到欧拉函数,或者是从质因子角度考虑也可以得到另外一个\(O(n)\)做法。

题目就是求

\[\prod_{i=1}^n\prod_{j=1}^n\frac{ij}{(i,j)^2}
\]

考虑分解一下

\[\prod_{i=1}^n\prod_{j=1}^n\frac{ij}{(i,j)^2}=\frac{\prod_{i=1}^n\prod_{j=1}^nij}{\prod_{i=1}^n\prod_{j=1}^n(i,j)^2}
\]

对于分子可得

\[\begin{aligned}
&\prod_{i=1}^n\prod_{j=1}^nij\\
&=\prod_{i=1}^ni\prod_{j=1}^nj\\
&=\prod_{i=1}^ni*n!\\
&=(n!)^{2n}
\end{aligned}
\]

对于分母,我们考虑莫比乌斯反演

\[\begin{aligned}
&\prod_{i=1}^n\prod_{j=1}^n(i,j)^2\\
&=\prod_{d=1}^nd^{2\sum_{i=1}^n\sum_{j=1}^n[(i,j)=d]}\\
&=\prod_{d=1}^nd^{2\sum_{i=1}^{\lfloor\frac{n}{d}\rfloor}\sum_{j=1}^{\lfloor\frac{n}{d}\rfloor}[(i,j)=1]}\\
&=\prod_{d=1}^nd^{2\sum_{k=1}^{\lfloor\frac{n}{d}\rfloor}\mu(k)\lfloor\frac{n}{kd}\rfloor^2}\\
\end{aligned}
\]

至此,枚举\(d\),对指数整除分块,即可\(O(n\sqrt{n})\)解决此题。

容易发现\(\lfloor\frac{n}{d}\rfloor\)是可以整除分块的。那么怎么处理区间\([l,r]\)的\(d\)呢,将它展开,其实就是\(\frac{r!}{(l-1)!}\),由于出题人卡空间,所以可以直接计算阶乘而不是预处理(复杂度同样是\(O(n)\),每个数只会被遍历一次)

那么就可以做到\(O(n)\)解决本题了。

  1. #include <cstdio>
  2. #include <algorithm>
  3. #define ll long long
  4. using namespace std;
  5. const int mod = 104857601;
  6. const int p = 104857600;
  7. const int N = 1000010;
  8. bool vis[N];
  9. short mu[N];
  10. int pr[N], cnt = 0;
  11. int fac;
  12. int power(int a, int b, int Mod) {
  13. int ans = 1;
  14. while(b) {
  15. if(b & 1) ans = (ll)ans * a % Mod;
  16. a = (ll)a * a % Mod;
  17. b >>= 1;
  18. }
  19. return ans % Mod;
  20. }
  21. void init(int n) {
  22. mu[1] = 1;
  23. for(int i = 2; i <= n; ++i) {
  24. if(!vis[i]) pr[++cnt] = i, mu[i] = -1;
  25. for(int j = 1; j <= cnt && i * pr[j] <= n; ++j) {
  26. vis[i * pr[j]] = 1;
  27. if(i % pr[j] == 0) break;
  28. mu[i * pr[j]] = -mu[i];
  29. }
  30. mu[i] += mu[i - 1];
  31. }
  32. fac = 1;
  33. for(int i = 1; i <= n; ++i) fac = (ll)fac * i % mod;
  34. }
  35. int n;
  36. int calc2(int n) {
  37. int ans = 0;
  38. for(int l = 1, r; l <= n; l = r + 1) {
  39. r = n / (n / l);
  40. ans = (ans + (ll)(n / l) * (n / l) % p * (mu[r] - mu[l - 1] + p) % p) % p;
  41. }
  42. return ans % p;
  43. }
  44. int main() {
  45. scanf("%d", &n);
  46. init(n);
  47. int ans = 1;
  48. int sum = power((ll)fac * fac % mod, n, mod);
  49. for(int l = 1, r; l <= n; l = r + 1) {
  50. r = n / (n / l); fac = 1ll;
  51. for(int i = l; i <= r; ++i) fac = (ll)fac * i % mod;
  52. int t = power((ll)fac * fac % mod, calc2(n / l), mod);
  53. ans = (ll)ans * t % mod;
  54. }
  55. printf("%lld\n", (ll)sum * power(ans, mod - 2, mod) % mod);
  56. }

LuoguP5221 Product的更多相关文章

  1. uva 11059 maximum product(水题)——yhx

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAB1QAAAMcCAIAAABo0QCJAAAgAElEQVR4nOydW7msuhKF2wIasIAHJK

  2. [LeetCode] Product of Array Except Self 除本身之外的数组之积

    Given an array of n integers where n > 1, nums, return an array output such that output[i] is equ ...

  3. [LeetCode] Maximum Product Subarray 求最大子数组乘积

    Find the contiguous subarray within an array (containing at least one number) which has the largest ...

  4. vector - vector product

    the inner product Givens two vectors \(x,y\in \mathbb{R}^n\), the quantity \(x^\top y\), sometimes c ...

  5. 1 Maximum Product Subarray_Leetcode

    Find the contiguous subarray within an array (containing at least one number) which has the largest ...

  6. Leetcode Maximum Product Subarray

    Find the contiguous subarray within an array (containing at least one number) which has the largest ...

  7. Where product development should start

    We all need to know our customers in order to create products they’ll actually buy. This is why the  ...

  8. [LintCode] Product of Array Except Self 除本身之外的数组之积

    Given an integers array A. Define B[i] = A[0] * ... * A[i-1] * A[i+1] * ... * A[n-1], calculate B WI ...

  9. sp_addlinkedserver '(null)' is an invalid product name

    使用SSMS 2008客户端工具逆向生成了创建链接服务器的脚本时,在测试环境执行是报如下错误:'(null)' is an invalid product name. USE [master] GO ...

随机推荐

  1. Python全栈-day15-day16-常用模块

    1.time模块 1)时间戳 import time# 通常来说,时间戳表示的是从1970年1月1日00:00:00开始按秒计算的偏移量 # 偏移量的是float类型 start_time = tim ...

  2. html5-列表

    <!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8&qu ...

  3. QNetworkAccessManager

    [1]头文件 想要利用QNetworkAccessManager类,必须在pro文件中添加对应库network,如下: QT += network 如果利用的VS + QT开发环境,请参考随笔< ...

  4. 【swiper轮播插件】解决swiper轮播插件触控屏问题

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  5. vue路由3:子路由

    <div id="app"> <div> <router-link to="/">首页</router-link> ...

  6. emmm

    #include <stdio.h> #include <stdlib.h> #include <iostream> using namespace std; st ...

  7. HDU 1232 畅通工程 (并查集)

    某省调查城镇交通状况,得到现有城镇道路统计表,表中列出了每条道路直接连通的城镇.省政府“畅通工程”的目标是使全省任何两个城镇间都可以实现交通(但不一定有直接的道路相连,只要互相间接通过道路可达即可). ...

  8. [转载]图解程序员必须掌握的Java常用8大排序算法

    这篇文章主要介绍了Java如何实现八个常用的排序算法:插入排序.冒泡排序.选择排序.希尔排序 .快速排序.归并排序.堆排序和LST基数排序,分享给大家一起学习. 分类1)插入排序(直接插入排序.希尔排 ...

  9. QT多线程简单例子

    在Qt中实现多线程,除了使用全局变量.还可以使用信号/槽机制. 以下例子使用信号/槽机制. 功能: 在主线程A界面上点击按钮,然后对应开起一个线程B.线程B往线程A发送一个字符串,线程A打印出来. 1 ...

  10. EditPlus配置Java

    --Java Compile-- 命令:D:\Program Files\Java\jdk1.7.0_79\bin\javac.exe 参数:$(FileName) 初始目录:$(FileDir) 动 ...