HDU 5666(二进制模仿乘法)
|
SegmentTime Limit: 2000/1000 MS (Java/Others)????Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 1560????Accepted Submission(s): 577Problem Description Input Output Sample Input 1 2 107? Sample Output 0? 说明(转自某博客): 按照题意,是让我们求该直线与第一象限组成的三角形地区中,坐标全为整数点的个数且不包罗所连直线的整数点个数,坐标轴上的不算。那么我们可以用地区内的整数点减去全部边上的整数点,就是我们的谜底。 1.起首我们求出三角形地区内的整数点,不包罗斜边上的点的总个数是,1+2+......+q-2=(q-1)*(q-2)/2. 2.然后我们求出(0,0)与斜边上各整数点的连线上整数点的个数。而(0,0)到(x0,y0)所组成的直线上(撤除(x0,y0)外),整数点的个数为gcd(x0,y0)-1. 下面证明一下这个结论...(0,0)到(x0,y0)这条直线方程为y=y0/x0 * x。上下同除以gcd(x0,y0)为,y = (y0/gcd)/(x0/gcd)*x..那么必定(y0/gcd)与(x0/gcd)是互质的,则y想为整数,则x必需为x0/gcd的整数倍,x范畴为0-x0,那么这个区间内的x0/gcd倍数个数为x0/(x0/gcd)=gcd,撤除端点(x0,y0),所觉得gcd(x0,y0)-1。。。。因此可以推广到一样平常的环境为(x0,y0)到(x1,y1)组成的直线上,整数点的个数为gcd(x1-x0,y1-y0). 以是我们求出gcd(x0,y0)-1即可,又由于x0+y0=q,且gcd(a,b)=gcd(a,a-b)(a>b)。。以是gcd(x0,y0)=gcd(x0,p-x0)=gcd(x0,p); ?p为质数,,那么gcd(x0,p)只也许是p的倍数可能为1,,又由于x,y是小于p的,,,(x+y=p嘛),,以是gcd(x0,p)=gcd(x0,y0)=1.。。。则gcd(x0,y0)-1=0,那么其余直线上是没有整数点的。因此最终的功效就是(q-1)*(q-2)/2.。。 3。留意坑,,q的范畴很大,,,(q-1)*(q-2)已经高出long long 了,以是要用到大数常识,,一是用Java的大数类办理,二是用二进制模仿大数乘法获得。。 代码:
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cstring>
#include <iostream>
using namespace std;
typedef long long int ll;
ll F(ll a,ll b,ll mod){ //二进制模仿乘法
ll ans = 0;
for( ; b>0; b/=2){
if(b%2){
ans += a;
ans %= mod;
}
a = 2*a%mod;
}
return ans;
}
int main(){
ll q,P;
int T;
scanf("%d",&T);
ll ans,tmp1,tmp2;
while(T--){
cin >> q;
cin >> P;
tmp1 = (q-1)/2;
tmp2 = q-2;
ans = F(tmp2,P);
cout << ans << endl;
}
return 0;
}
(编辑:湖南网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |

