题目大意 多组数据,每组数据给定两个整数 \(n,m\),请求出 \(n\times m\) 的点阵(即 \((n-1)\times(m-1)\) 的方格)中有多少条非水平竖直的经过至少两个格点的不同直线。

分析 这道题有多种解法,这里给出最经典的,使用容斥原理的解法。

令 \(dp[i][j]\) 表示 \(i\times j\) 的方格中,经过 \((0,0)\) 顶点的所有至少经过两个点的不同直线数(比如 \(dp[3][2]=5\))。

不难发现,\(dp\) 数组满足可加可减性,也即可以用容斥原理来递推。且点 \((i,j)\) 当且仅当 \(GCD(i,j)=1\) 时可以为 \(dp[i][j]\) 贡献 \(1\)。所以有

\[dp[i][j]=dp[i-1][j]+dp[i][j-1]-dp[i-1][j-1]+[gcd(i,j)=1]
\]

现在考虑如何用 \(dp\) 数组来递推出最终答案。我们记 \(i\times j\) 方格中从左下到右上的不同直线数为 \(ans[i][j]\),则最终答案为 \(2\times ans[i][j]\)(比如 \(ans[3][2]=14\))。

不难看出,\(ans\) 数组也满足可加可减性,可以用容斥原理来递推。且点 \((i,j)\) 构成的新直线当且仅当它在 \(dp[i][j]\) 中而不在 \(dp[i/2][j/2]\) 中才有贡献,这是因为如果它在被重复计算过则一定在 \(dp[i/2][j/2]\) 中被计算过(为什么),所以有

\[ans[i][j]=ans[i-1][j]+ans[i][j-1]-ans[i-1][j-1]+dp[i][j]-dp[i/2][j/2]
\]

#include<bits/stdc++.h>
using namespace std; const int maxn = 305;
const int maxm = 305; int n, m;
int dp[maxn][maxm];
int ans[maxn][maxm]; void Init(int N, int M)
{
for(int i = 1; i <= N; ++i)
for(int j = 1; j <= M; ++j)
dp[i][j] = dp[i - 1][j] + dp[i][j - 1] - dp[i - 1][j - 1] + (__gcd(i, j) == 1); for(int i = 1; i <= N; ++i)
for(int j = 1; j <= M; ++j)
ans[i][j] = ans[i - 1][j] + ans[i][j - 1] - ans[i - 1][j - 1] + dp[i][j] - dp[i / 2][j / 2];
} int main()
{
Init(300, 300);
while(~scanf("%d%d", &n, &m) && n && m)
printf("%d\n", 2 * ans[n - 1][m - 1]);
}

最新文章

  1. Revolving Digits(hdu 4333)
  2. [工具开发] keepalived使用nagios监控脚本
  3. ubuntu虚拟机安装
  4. Linux scp 远程文件/目录传输
  5. C++引用变量学习
  6. 怎样利用putty登陆SSH主机方法
  7. Headroom.js
  8. 流动python - 写port扫描仪和各种并发尝试(多线程/多进程/gevent/futures)
  9. js局部变量,参数
  10. Struts2的validator和WEB-INF下页面交互以及路径问题
  11. echarts图表变形解决方案
  12. Beta Scrum Day 7
  13. STS中applicationContext.xml配置文件
  14. 接口自动化思路_JAVA
  15. C#的抽象类别
  16. CentOS6.9下升级默认的OpenSSH操作记录(升级到OpenSSH_7.6p1)
  17. Dubbo原理和源码解析之“微内核+插件”机制
  18. 微信UnionId 部分开放
  19. ECharts之饼图和柱形图demo
  20. class字节码结构(四)(方法集合的结构)

热门文章

  1. [转载] iptables 防火墙设置
  2. Python 数据类型,常用函数方法分类
  3. 【React】 npm 常用的插件
  4. tensorflow在文本处理中的使用——Doc2Vec情感分析
  5. centos7中安装R之前yum依赖的包
  6. chrome查看当前网页cookie内容
  7. Sybase commands
  8. com.mysql.jdbc.PacketTooBigException: Packet for query is too large (1680 &gt; 1024). You can change this value on the server by setting the max_allowed_packet&#39; variable.
  9. JavaScript中浅拷贝和深拷贝的区别
  10. IE框架表单遍历