zoukankan      html  css  js  c++  java
  • 【Luogu P2508】 [HAOI2008]圆上的整点

    题目大意:

    求一个给定的圆 ((x^2+y^2=r^2)),在圆周上有多少个点的坐标是整数。

    正文:

    声明: 此方法概括(转)自 3b1b 的视频

    如果我们直接照着题目给出的勾股定理枚举,最优解的时间复杂度似乎就只有 (O(r)),可 (r) 达到二十亿,这方法觉得行不通。

    数学里比较常见的是,当你看到和二维平面有关的问题时,就把这个平面看成全体复数的集合,再看问题或许会有意外收获
    ——3blue1brown

    up主给我的启示很有用。当在半径是 (5) 的圆周上,有一个整点的坐标是 ((x,y)),那么将二维平面转换成复平面,那个整点也跟着转换成一个复数 (Z=x+yi)

    图1

    (图中 (Z=3+4i)

    那么半径 (egin{aligned}r & = overrightarrow{AB} \ & = sqrt{x^2+y^2} \ & = (x+yi)(x-yi)end{aligned})。这样问题就可以转为分解质因数。

    而所有满足这样的整数就是高斯整数。问题就是求有多少个高斯整数能满足其自身与其复共轭的积是圆的半径。我们可以通过分解质因数的方式求出高斯整数的数目。如质数 (5),它能分解成一个高斯整数 ((2+i))。但只有模四余一的质数才会对答案有贡献,如质数 (7),不能分解质数。

    代码:

    int main()
    {
    	scanf ("%lld", &r);
    	prime(100000);
    	for (int i = 1; i <= cnt; i++)
    	{
    		int num = 0;
    		for (; r % pri[i] == 0;r/=pri[i],num++);
    		if (pri[i] % 4 == 1) ans *= num * 2 + 1ll;  //每个质数的贡献,乘2是因为视频里是根号r,这里是r,质因数翻倍
    	}
    	if(r > 1 && r % 4 == 1)ans *= 3;  //当半径模四余一的特例
    	printf("%lld", ans * 4ll); //复数及其复共轭皆可乘虚数i,一共四种
    	return 0;
    }
    
  • 相关阅读:
    Eclipse 安装Activiti插件(BPMN打开工具)
    POI Excel 单元格内容类型判断并取值
    AJAX获取数据成功后的返回数据如何声明成全局变量
    java 思维导图
    java excel Workbook API
    金额 保留两位小数
    mybatis教程3(映射文件)
    mybatis教程1(基本使用)
    mybatis教程之原理剖析
    Maven教程4(私服-nexus)
  • 原文地址:https://www.cnblogs.com/GJY-JURUO/p/13341673.html
Copyright © 2011-2022 走看看