题意

给你一个\(n*m\)方格图,统计上面有多少个格点三角形,除了三个顶点,不覆盖其他的格点(包括边和内部).

答案对于\(998244353\)取模... (\(n,m \le 5 * 10^9\))

题解

这个题十分的巧妙... 集训时是大佬ztzshiwo出的..

据他所说,是不那么杜教筛的杜教筛QAQ

考试时候提示了一个皮克定理...

皮克定理:

\[S=a+\frac{b}{2}-1
\]

\(S\)为格点多边形面积,\(a\)为多边形内部点数,\(b\)为多边形边上点数.

然而我还是只会暴力,正解是真的太神了啊QAQ.

我们考虑一个\(a*b\)的矩形,以它对顶点为端点的三角形,只当\(a \bot b\)时存在四个解.

这个我是听wearry证明的qwq 十分巧妙

简单的证明:

代入皮克定理,可知

当且仅当格点三角形面积为\(S=0+\frac{3}{2}-1=\frac{1}{2}\)时才计入答案

我们可以用叉积的形式表示这个面积. \(S=\frac{1}{2} |AB| |BC| \sin \theta =\frac{1}{2} |\vec {AB} \times \vec{AC}|\).(高中必修内容QAQ)

![image](http://images.cnblogs.com/cnblogs_com/zjp-shadow/1056673/t_sol.png)

我们令之前那个矩形的一条对角线为三角形的一条边,

令左下角为向量出发点,也就是其中一个顶点,然后这条边的向量坐标表达就为\((a,b)\).

我们令另外一条边为\((i,j)\),然后三角形面积就是\(\frac{1}{2}|(a,b) \times (i,j)| = \frac{1}{2}|aj - bi|\).

这个为\(\frac{1}{2}\)所以\(|aj-bi|=1\). \(\therefore aj-bi= \pm 1\)

我们是要求解\((i,j)\) 所以不难发现这是一个扩欧的形式,当且仅当\(a \bot b\)时有整数解.

又\(\because 0 < i < a, 0 < j < b\).. \(\therefore\)可以通过扩欧的相邻解确定在这个区域仅一解.

所以\(\pm 1\)各有一解,换个对角线又有对称的一组解.所以最后总共\(2*2=4\)组解.

所以我们要求的就是原图中每个矩形的贡献就行了...

此处\(n\),\(m\)都是要减一的... (至于为啥...手推就知道了QAQ)

\[\displaystyle \mathrm {ans}=\sum_{i=1}^{n} \sum _{j=1}^{m} 4 \cdot (n-i)(m-j) [i \bot j]
\]

\[\displaystyle =4\sum_{i=1}^{n} \sum_{j=1}^{m} (n-i)(m-j) \sum _ {x|\gcd (i,j)} \mu(x)
\]

\[=\displaystyle 4 \sum_{x=1}^{min(n,m)} \mu(x) \sum_{i=1}^{\lfloor \frac{n}{x} \rfloor} \sum_{j=1}^{\lfloor \frac{m}{x} \rfloor} nm - mix - njx + ijx^2
\]

令$$\displaystyle S(i)=\sum_{i=1}^{n} i = \frac{n(n+1)}{2}$$.

\[\displaystyle \mathrm{sum1}=nm \sum_{x=1}^{min(n,m)} \mu(x) \lfloor \frac{nm}{x^2} \rfloor
\]

\[\displaystyle \mathrm{sum2}=m \sum_{x=1}^{min(n,m)} (\mu(x) \cdot x) S(\lfloor \frac{n}{x} \rfloor) \lfloor \frac{m}{x} \rfloor
\]

\[\displaystyle \mathrm{sum3}=n \sum_{x=1}^{min(n,m)} (\mu(x) \cdot x) \lfloor \frac{n}{x} \rfloor S(\lfloor \frac{m}{x} \rfloor)
\]

\[\displaystyle \mathrm{sum4}=\sum_{x=1}^{min(n,m)} (\mu(x) \cdot x^2) S(\lfloor \frac{n}{x} \rfloor) S(\lfloor \frac{m}{x} \rfloor)
\]

\[\mathrm{ans}=\mathrm{sum1}-\mathrm{sum2}-\mathrm{sum3}+\mathrm{sum4}
\]

这个用根号分块就能做到\(\Theta (n+\sqrt {n})\)复杂度啦... 具体推导证明看我的一篇博客线性筛与莫比乌斯反演.

然而这并不能满分...fuck

所以就有杜教筛卡了30分.

\(\displaystyle \sum _{i=1}^{n} \mu(i)\)之前那篇博客杜教筛小结中有介绍.

然后就介绍另外两个套路求的东西吧..

令\(\displaystyle id(x)=x, mx(x)= \mu(i) i\). (然后之后默认把第一个字母大写记作前缀和比如\(\displaystyle Id(x)=\sum_{i=1}^{x} id(i) = \frac{x(x+1)}{2}\))

所以就有

\[mx * id (n)
\]

\[\displaystyle = \sum _{d|n} \mu(d) \cdot d \cdot \frac{n}{d} =\displaystyle \sum _{d|n} \mu(d) \cdot n
\]

\[=\displaystyle n \sum_{d|n} \mu(d) = n \cdot [n=1] = \epsilon
\]

代入之前的套路式子就有

\[\displaystyle 1 - Mx(n) = \sum _{i=2}^{n} i \cdot Mx(\lfloor \frac{n}{i} \rfloor)
\]

然后就可以尝试推出\(\displaystyle \sum _{i=1}^{n} \mu(i) \cdot i \cdot i\).

这个也不麻烦QAQ...

然后本人比较懒 就直接用c++11 中的unordered_map了(这个基于哈希算法)

有些地方有点细节\(5*10^9 * 5*10^9 = 2.5 * 10^{19}\)会爆long long所以很多地方都要记得先取模!!!

代码

  1. #include <bits/stdc++.h>
  2. #define For(i, l, r) for(register ll i = (l), _end_ = (ll)(r); i <= _end_; ++i)
  3. #define Fordown(i, r, l) for(register ll i = (r), _end_ = (ll)(l); i >= _end_; --i)
  4. #define Set(a, v) memset(a, v, sizeof(a))
  5. using namespace std;
  6. typedef long long ll;
  7. inline ll read() {
  8. ll x = 0, fh = 1; char ch = getchar();
  9. for (; !isdigit(ch); ch = getchar() ) if (ch == '-') fh = -1;
  10. for (; isdigit(ch); ch = getchar() ) x = (x<<1) + (x<<3) + (ch ^ '0');
  11. return x * fh;
  12. }
  13. void File() {
  14. #ifdef zjp_shadow
  15. freopen ("1456.in", "r", stdin);
  16. freopen ("1456.out", "w", stdout);
  17. #endif
  18. }
  19. const ll Mod = 998244353;
  20. ll n, m;
  21. const int N = 1e7 + 1e3;
  22. int prime[N], cnt = 0;
  23. int Limit = N - 1e3;
  24. ll mux[N], muxx[N], mu[N];
  25. bitset<N> is_prime;
  26. void Init(int maxn) {
  27. int res;
  28. mu[1] = 1;
  29. is_prime.set(); is_prime[0] = is_prime[1] = false;
  30. For (i, 2, maxn) {
  31. if (is_prime[i]) { prime[++cnt] = i; mu[i] = -1; }
  32. For (j, 1, cnt) {
  33. res = prime[j] * i;
  34. if (res > maxn) break;
  35. is_prime[res] = false;
  36. if (i % prime[j]) mu[res] = -mu[i];
  37. else { mu[res] = 0; break ; }
  38. }
  39. }
  40. For (i, 1, maxn) {
  41. mux[i] = mux[i - 1] + 1ll * mu[i] * i % Mod;
  42. mux[i] = (mux[i] % Mod + Mod) % Mod;
  43. muxx[i] = muxx[i - 1] + 1ll* mu[i] * i % Mod * i % Mod;
  44. muxx[i] = (muxx[i] % Mod + Mod) % Mod;
  45. mu[i] += mu[i - 1];
  46. mu[i] = (mu[i] % Mod + Mod) % Mod;
  47. }
  48. }
  49. ll fpm(ll x, ll power) { ll res = 1; x %= Mod; for (; power; power >>= 1, (x *= x) %= Mod) if (power & 1) (res *= x) %= Mod; return res; }
  50. const ll inv2 = fpm(2, Mod - 2), inv6 = fpm(6, Mod - 2);
  51. ll Sum(ll x) { x %= Mod; return (x + 1) * x % Mod * inv2 % Mod; }
  52. ll sum1, sum2, sum3, sum4;
  53. ll Nextx;
  54. unordered_map<ll, ll> MU, MUX, MUXX;
  55. ll mu_(ll x) {
  56. if (x <= Limit) return mu[x];
  57. if (MU.count(x)) return MU[x];
  58. ll res = 1, Nextx;
  59. For (i, 2, x) { Nextx = x / (x / i); (res += Mod - (Nextx - i + 1) * mu_(x / i) % Mod) %= Mod; i = Nextx; }
  60. return (MU[x] = res);
  61. }
  62. inline ll Sum1(ll x) { x %= Mod; return x * (x + 1) % Mod * inv2 % Mod; }
  63. ll mux_(ll x) {
  64. if (x <= Limit) return mux[x];
  65. if (MUX.count(x)) return MUX[x];
  66. ll res = 1, Nextx;
  67. For (i, 2, x) { Nextx = x / (x / i); (res += Mod - (Sum1(Nextx) - Sum1(i - 1) + Mod) * mux_(x / i) % Mod) %= Mod; i = Nextx; }
  68. return (MUX[x] = res);
  69. }
  70. inline ll Sum2(ll x) { x %= Mod ; return x * (x + 1) % Mod * (2 * x + 1) % Mod * inv6 % Mod; }
  71. ll muxx_(ll x) {
  72. if (x <= Limit) return muxx[x];
  73. if (MUXX.count(x)) return MUXX[x];
  74. ll res = 1, Nextx;
  75. For (i, 2, x) { Nextx = x / (x / i); (res += Mod - (Sum2(Nextx) - Sum2(i - 1) + Mod) * muxx_(x / i) % Mod) %= Mod; i = Nextx; }
  76. return (MUXX[x] = res);
  77. }
  78. int main () {
  79. File();
  80. n = read(); m = read();
  81. if (n > m) swap(n, m);
  82. Init(Limit);
  83. For (x, 1, n) {
  84. Nextx = min(n / (n / x), m / (m / x));
  85. (sum1 += (mu_(Nextx) - mu_(x - 1)) * (n / x) % Mod * (m / x) % Mod * n % Mod * m % Mod) %= Mod;
  86. (sum2 += (mux_(Nextx) - mux_(x - 1)) * Sum(n / x) % Mod * (m / x) % Mod) %= Mod;
  87. (sum3 += (mux_(Nextx) - mux_(x - 1)) * Sum(m / x) % Mod * (n / x) % Mod) %= Mod;
  88. (sum4 += (muxx_(Nextx) - muxx_(x - 1)) * Sum(n / x) % Mod * Sum(m / x) % Mod) %= Mod;
  89. x = Nextx;
  90. }
  91. ll ans = sum1 - 1ll * m * sum2 % Mod - 1ll * n * sum3 % Mod + sum4;
  92. ans = (ans % Mod + Mod) % Mod;
  93. ans = ans * 4ll % Mod;
  94. printf ("%lld\n", ans);
  95. return 0;
  96. }

hihocoder #1456 : Rikka with Lattice(杜教筛)的更多相关文章

  1. 51nod 1244 莫比乌斯函数之和(杜教筛)

    [题目链接] http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1244 [题目大意] 计算莫比乌斯函数的区段和 [题解] 利 ...

  2. 51nod 1237 最大公约数之和 V3(杜教筛)

    [题目链接] https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1237 [题目大意] 求[1,n][1,n]最大公约数之和 ...

  3. 杜教筛 && bzoj3944 Sum

    Description Input 一共T+1行 第1行为数据组数T(T<=10) 第2~T+1行每行一个非负整数N,代表一组询问 Output 一共T行,每行两个用空格分隔的数ans1,ans ...

  4. 51NOD 1220 约数之和 [杜教筛]

    1220 约数之和 题意:求\(\sum_{i=1}^n \sum_{j=1}^n \sigma_1(ij)​\) \[ \sigma_0(ij) = \sum_{x\mid i}\sum_{y\mi ...

  5. BZOJ 4176: Lucas的数论 [杜教筛]

    4176: Lucas的数论 题意:求\(\sum_{i=1}^n \sum_{j=1}^n \sigma_0(ij)\) \(n \le 10^9\) 代入\(\sigma_0(nm)=\sum_{ ...

  6. 51NOD 1222 最小公倍数计数 [莫比乌斯反演 杜教筛]

    1222 最小公倍数计数 题意:求有多少数对\((a,b):a<b\)满足\(lcm(a,b) \in [1, n]\) \(n \le 10^{11}\) 卡内存! 枚举\(gcd, \fra ...

  7. 51NOD 1237 最大公约数之和 V3 [杜教筛]

    1237 最大公约数之和 V3 题意:求\(\sum_{i=1}^n\sum_{j=1}^n(i,j)\) 令\(A(n)=\sum_{i=1}^n(n,i) = \sum_{d\mid n}d \c ...

  8. 【BZOJ4805】欧拉函数求和(杜教筛)

    [BZOJ4805]欧拉函数求和(杜教筛) 题面 BZOJ 题解 好久没写过了 正好看见了顺手切一下 令\[S(n)=\sum_{i=1}^n\varphi(i)\] 设存在的某个积性函数\(g(x) ...

  9. 我也不知道什么是"莫比乌斯反演"和"杜教筛"

    我也不知道什么是"莫比乌斯反演"和"杜教筛" Part0 最近一直在搞这些东西 做了将近超过20道题目吧 也算是有感而发 写点东西记录一下自己的感受 如果您真的 ...

随机推荐

  1. 【Java】多线程初探

     参考书籍:<Java核心技术 卷Ⅰ >   Java的线程状态   从操作系统的角度看,线程有5种状态:创建, 就绪, 运行, 阻塞, 终止(结束).如下图所示     而Java定义的 ...

  2. “茴”字有四种写法,this也是一样

    说到这个地方又想起以前高中还是初中学的<孔乙己>这个梗,但是这里的this显然实用性比那个要大很多,哈哈. 简单来说,this有四种应用场景,分别是在构造函数上.对象属性中.普通函数中.c ...

  3. centos 6.8 下安装redmine(缺陷跟踪系统)

    一.实验环境 centos6.8 64位 所需安装包: ruby-2.3.4.tar.gz.rubygems-1.8.25.tgz.redmine-2.3.2.tar.gz 二.安装步骤 1.安装必要 ...

  4. css3渐变 transition使用方法

    <style> div{ width:300px; height:300px; background:#89F; margin:100px auto; transition:width 1 ...

  5. window 下生成NodeJs(v8.9.3) 的 VS2015 解决方案node.sln

    window 下生成NodeJs(v8.9.3) 的 VS2015 解决方案node.sln 使用步骤 也可以参照 github: https://github.com/nodejs/node/blo ...

  6. [记]WIndow/Linux 获取本机(全部)IPv4、IPv6、MAC地址方法 (C/C++)

    Linux 获取本机IP.MAC地址用法大全 //#include <sys/types.h> #include <ifaddrs.h> #include <sys/io ...

  7. Pycharm 出现Unresolved reference '' 错误的解决方法

    在用Pycharm做Pygame游戏小实战的时候碰到一个很无语的问题 如下 什么鬼?????? 我明明有写settings模块啊 而且还是放在同一个目录下  然后Pycharm给我来了一个错误 而且在 ...

  8. bzoj 1307/1318 玩具 线段树+记录时间戳

    玩具 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 743  Solved: 404[Submit][Status][Discuss] Descrip ...

  9. 初识vue——语法初解

    这次我们按照官网上的教程对vue的语法进行一个初步的了解: 一.声明式渲染 Vue.js的核心是一个允许采用简洁的模板语法来声明式的将数据渲染仅DOM的系统: 1.我们在HelloWorld里面输入下 ...

  10. 求指定区间内与n互素的数的个数 容斥原理

    题意:给定整数n和r,求区间[1, r]中与n互素的数的个数. 详细见容斥定理 详细代码如下 int solve(int r, int n) { vector<int>p; p.clear ...