数论某些题目

平面上有一个圆, 圆心坐标为(0,0),半径为n. 问圆周上有多少个整点. 整点的定义即x,y坐标均为整数的点.

做题过程:思考后感觉有点难度,可能用到一些奇怪的知识,于是决定去看题解;

题解:

1.一般人都能想到x2+y2=r2这一点,但是仅想到这一点并没什么用;

2.变形:

   移项得:r2-x2=y2

   得y2=(r-x)(r+x)

   设d=gcd((r-x),(r+x))

   则设A=(r-x)/d,B=(r+x)/d

   代入原式得 y2=ABd2

   因为gcd(A,B)=1

   所以A,B均为完全平方数

   设a2=A,b2=B

   可得a2+b2=2r/d

3.得到上面的式子,d很显然是2r的约数,可以枚举d;

在枚举d时,可以枚举a,算出b,若gcd(a,b)等于1,则ans++即可;

个人理解:实际上它这个最后的式子相比于最初的式子有什么优点呢?

第一个是r的次数由2次方变成了一次方,于是就可以发现原来的一个O(n)级别的算法成了根号级别的算法;

本质上是通过数学运算除去原本枚举时的无用状态;

代码:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<string>
 5 #include<ctime>
 6 #include<algorithm>
 7 #include<cstdlib>
 8 #include<map>
 9 #include<set>
10 #include<vector>
11 #include<queue>
12 using namespace std;
13 #define FILE "dealing"
14 #define LL long long
15 #define up(i,j,n) for(int i=j;i<=n;i++)
16 #define pii pair<int,int>
17 #define piii pair<int,pair<int,int> >
18 template<typename T> inline bool chkmin(T &a,T b){return a>b?a=b,true:false;}
19 namespace IO{
20     char *fs,*ft,buf[1<<15];
21     inline char gc(){return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:*fs++;}
22     inline int read(){
23         int x=0,ch=gc();bool f=0;
24         while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=1;ch=gc();}
25         while(ch<=‘9‘&&ch>=‘0‘){x=(x<<1)+(x<<3)+ch-‘0‘;ch=gc();}
26         return f?-x:x;
27     }
28 }using namespace IO;
29 namespace OI{
30     LL n;
31     LL gcd(LL a,LL b){return b==0?a:gcd(b,a%b);}
32     LL cnt=0;
33     void slove(){
34         scanf("%lld",&n);
35         for(LL d=1;d*d<=2*n;d++){
36             if(!(2*n%d)){
37                 for(LL a=1;a*a<=(n/d);a++){
38                     LL b=(LL)sqrt(2.0*n/d-a*a);
39                     if(a*a+b*b==2*n/d&&gcd(a,b)==1&&a!=b)cnt++;
40                 }
41                 d=2*n/d;
42                 for(LL a=1;a*a<=(n/d);a++){
43                     LL b=(LL)sqrt(2.0*n/d-a*a);
44                     if(a*a+b*b==2*n/d&&gcd(a,b)==1&&a!=b)cnt++;
45                 }
46                 d=2*n/d;
47             }
48         }
49         cnt=4*cnt+4;
50         printf("%lld\n",cnt);
51     }
52 }
53 int main(){
54     freopen(FILE".in","r",stdin);
55     freopen(FILE".out","w",stdout);
56     using namespace OI;
57     slove();
58     return 0;
59 }

时间: 2024-08-05 11:15:55

数论某些题目的相关文章

数论基础题目八题【欧几里得】【筛法素数】【中国剩余定理】

之前看的数论的知识,现在做几道题目找找感觉..... poj 1061 传送门 题目大意,给你x,y,m,n,L.代表青蛙a的坐标x,青蛙b的坐标y,青蛙a一次跳的距离m,青蛙b一次跳的距离n,以及mod的值L,求经过多少次跳相遇.即求:(m-n)*x0=(x-y)(mod L);  模线性方程的解,不过要注意处理,因为(m-n)和(x-y)有可能是负的,如果(m-n)是负的,则直接对俩数取负数,下面就是对 ((x-y)+L)%L. 然后就能用modular_linear_equation(LL

数论poj题目

http://blog.sina.com.cn/s/blog_76f6777d0101ir50.html 1.素数,整数分解,欧拉函数 素数是可能数论里最永恒,最经典的问题了.素数的判断,筛法求素数,大素数的判断···还有很多其他问题都会用到素数. *最水最水的:(心情不爽时用来解闷吧) pku1365 Prime Land pku2034 Anti-prime Sequences pku2739 Sum of Consecutive Prime Numbers pku3518 Prime Ga

数论小结1.

从白书上面的习题开始版切....但是发现时间不够了.... 今天粗略的做了不少题目.....但是有些题目感觉实在是比较诡异.......感觉考的话也不太可能...不过还是写下来吧. 1.Uva 10673 已知x, k, 求 x = p * floor(x / k) + q * ceil(x / k).的解. 思路: 其实分类讨论就 ok 了. 当 x % k == 0 时, 取 p = x * k, q = 0; 否则, floor 与 ceil 相差 1. 怎么做? 你懂得. 2. Uva

【数论】约瑟夫问题

约瑟夫问题     约瑟夫问题是一类经典的又非常简单的基础数论问题     题目大意(选班长):          N个人围成一个圈,依次编号为0..N-1.然后随机抽选一个数K,并0号候选人开始按从1到K的顺序依次报数,N-1号候选人报数之后,又再次从0开始.当有人报到K时,这个人被淘汰,从圈里出去.下一个人从1开始重新报数.最后一个人即是班长. 换成示意图即是这样:     设N=5,K=3     1:从0开始报数,报到K,也就是2,2退出          2:从3开始报数,遇到4返回0

UVA10519 - !! Really Strange !!(数论+高精度)

10519 - !! Really Strange !!(数论+高精度) 题目链接 题目大意:给你n个圆,每两个圆都有相交的部分,并且相交的两个点都唯一的,不能再和别的圆交于这点.问这样在一个矩形里的相交的n个圆可以产生多少个新的封闭图形.看图会明白的. 解题思路:规律:f(n) = f(n - 1) + 2 ?(n - 1) 最后推的 f(n) = n ? (n - 1) + 2; (n >= 1), 0的时候要特判.n本身就是个大数,结果也是个大数. 代码: import java.util

LightOJ 1336 Sigma Function(数论 整数拆分推论)

--->题意:给一个函数的定义,F(n)代表n的所有约数之和,并且给出了整数拆分公式以及F(n)的计算方法,对于一个给出的N让我们求1 - N之间有多少个数满足F(x)为偶数的情况,输出这个数. --->分析:来考虑F(x)为奇数的情况,给据题目中给我们的公式,,如果F(x)为奇数,那么这个多项式里面的任何一项都必须是奇数,可以知道p = 2时,        p^e - 1肯定是奇数,如果p != 2,当且仅当e为偶数的时候,此项为奇数,证明如下: 原式变形为[ p^(e+1) -p + (

数论 UVA 11889

有关数论的题目,题目大意是给你两个数a和c,c为a和另一个数b的最小公倍数,要求你求出b的最小值.由最大公约数gcd(a,b)和最小公倍数lcm(a,b)之间的关系可知,lcm(a,b)*gcd(a,b)=a*b; 则b=lcm(a,b)*gcd(a,b)/a,b=c*gcd(a,b)/a,b/gcd(a,b)=c/a.因为c/a是b除去gcd(a,b)后的部分.若gcd(a,c/a)=1,就表明c/a就是我们要求的答案:否则,就说明c/a小于b,需要还原.还原 的过程中,首先求出gcd(a,c

图论 - 数论 - 生成树

图论 - 数论 - 生成树 题目链接:https://www.luogu.org/problem/P3366 代码: #include <bits/stdc++.h> using namespace std; const int N = 5010; const int M = 200010; int n, m, dis[N], ans; int tot, head[N], val[M << 1], nxt[M << 1] ,to[M << 1]; bool

LightOJ 1336 Sigma Function

/* LightOJ 1336 Sigma Function http://lightoj.com/login_main.php?url=volume_showproblem.php?problem=1336 数论 奇偶性 题目求f(n)为偶数的个数 我们发现如果f(n)为奇数,则n为x^2,2*x^2,2^x三种形式, 因为2^x中已经包含剩下两种, 所以只需求x^2和2*x^2的个数即可求得答案. * 打了半天表发现没用233333 * */ #include <cstdio> #incl