传送门
1 2 107
0
题目大意:
Rivendell非常神,喜欢研究奇怪的问题.
今天他发现了一个有趣的问题.找到一条线段x+y=q,令它和坐标轴在第一象限围成了一个三角形,然后画线连接了坐标原点和线段上坐标为整数的格点.
请你找一找有多少点在三角形的内部且不是线段上的点,并将这个个数对P取模后告诉他.
官方题解:
考虑一条以(0,0)为起点,(x,y)为终点的线段上格点的个数(不包含端点时),一定是gcd(x,y)−1,这个很显然吧.
然后整个网格图范围内的格点数目是2q∗(q−1).
所以答案就是2q∗(q−1)− 所有线段上的格点的个数.
因为gcd(a,b)=gcd(a,b−a) (b>a),所以gcd(x,y)=gcd(x,p−x)=gcd(x,p),p是质数,所以gcd(x,y)=1,所以线段上都没有格点,所以答案就是2q∗(q−1).
个人想法:其实自己就是画一个图,一定是方格图,然后自己画一下,就会发现一些规律,其实每个点一行一行的可以构成一个等差数列,所以相加得到的公式就是 (q-1)*(q-2)/2,注意 两个数相乘会爆long long,所以采用快速乘法 二进制那个给优化一下就搞定了:
My Code:
#include <iostream> #include <cstdio> #include <cstring> using namespace std; typedef long long LL; LL Mul_mod(LL a, LL b, LL m) { LL ans = 0; while(b) { if(b & 1) ans = (ans+a)%m; b>>=1; a = (a+a)%m; } return ans; } int main() { int T; scanf("%d",&T); while(T--) { LL q, mod; cin>>q>>mod; LL x1 = q - 1; LL x2 = q - 2 ; if(x1%2==0) x1>>=1; else x2>>=1; printf("%lld\n",Mul_mod(x1,x2,mod)); } return 0; }