您的位置:首页 > 其它

Hdu 5666 Segment【欧拉函数+技巧乘法】

2016-04-19 22:42 246 查看

Segment

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)

Total Submission(s): 999 Accepted Submission(s): 360

[align=left]Problem Description[/align]
Silen
August does not like to talk with others.She like to find some interesting problems.

Today
she finds an interesting problem.She finds a segment
x+y=q.The
segment intersect the axis and produce a delta.She links some line between
(0,0)
and the node on the segment whose coordinate are integers.

Please
calculate how many nodes are in the delta and not on the segments,output answer mod P.

[align=left]Input[/align]
First
line has a number,T,means testcase number.

Then,each
line has two integers q,P.

q
is a prime number,and 2≤q≤1018,1≤P≤1018,1≤T≤10.

[align=left]Output[/align]
Output
1 number to each testcase,answer mod P.

[align=left]Sample Input[/align]

1
2 107

[align=left]Sample Output[/align]

0

[align=left]Source[/align]
BestCoder Round #80 

题意:

给出  x+y=q 的q


确定q 是素数,连接这条线上所有的格点和原点,求在第一象限中,在由坐标轴和这条直线围成的三角形中,但不在这些线上的所有的格点的个数.



如图,求在大三角中,但是不在红线以及坐标轴上的点的个数

题解:

首先是没读懂题意,直接交了前n 项和,wa.....

后来看明白题意了,瞬间感觉是求欧拉函数,然后各种找规律....联系曾今做过的几个欧拉函数的题目

终于发现了规律!!

(n-2)*euler(n)/2   

然后各种wa.....后来才发现数据范围太大,会中间溢出啊!!

想起前几天学到的取余的方法:把乘法用加法和移位来代替,这样就不会溢出啦~

顺利AC!

/* http://blog.csdn.net/liuke19950717 */
#include<cstdio>
#include<cstring>
#include<cmath>
typedef unsigned long long ll;
ll euler(ll x)
{
ll sum=x;
for(ll i=2;i*i<=x;++i)
{
if(x%i==0)
{
x/=i;
sum=sum-sum/i;
while(x%i==0)
{
x/=i;
}
}
}
if(x>1)
{
sum=sum-sum/x;
}
return sum;
}
ll mul(ll n,ll m,ll mod)
{
ll ans=0;
while(m)
{
if(m&1)
{
ans=(ans+n)%mod;
}
m>>=1;
n=(n<<1)%mod;
}
return ans;
}
int main()
{
ll t;
scanf("%lld",&t);
while(t--)
{
ll n,mod;
scanf("%lld%lld",&n,&mod);
ll ans=mul(n-2,euler(n)/2,mod);
printf("%lld\n",ans%mod);
}
return 0;
}


后来整理思路,发现自己走了弯路,因为给出的n 必定为素数,而素数对应的欧拉函数值就是他自身减去1,程序就可以省去一个求解欧拉函数的了,这道题也就成了完全考验找规律和技巧性取模的题目了.....

/* http://blog.csdn.net/liuke19950717 */
#include<cstdio>
#include<cstring>
#include<cmath>
typedef unsigned long long ll;
ll mul(ll n,ll m,ll mod)
{
ll ans=0;
while(m)
{
if(m&1)
{
ans=(ans+n)%mod;
}
m>>=1;
n=(n<<1)%mod;
}
return ans;
}
int main()
{
ll t;
scanf("%lld",&t);
while(t--)
{
ll n,mod;
scanf("%lld%lld",&n,&mod);
ll ans=mul(n-2,(n-1)/2,mod);
printf("%lld\n",ans%mod);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: