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;
}
相关文章推荐
- ACM第二次练习—1013&1014
- BZOJ4518 && SDOi2016 征途
- Python 获取本机ip地址
- 欢迎使用CSDN-markdown编辑器
- awk的用法
- oracle学习 第四章 单行函数 ——01
- 电子相册系统(三)使用技术
- zabbix 3.0 脚本调用
- Strange fuction
- MATLAB axis和axes的区别
- Install Git--MacOs X
- 【Android】图片切割
- lwip C/S模型调试 抓包看到常见的错误状态
- 从头认识多线程-1.16 对比不同的优先级
- <Puppet 集中配置管理系统RHEL6>
- ios 音视频处理优化总结
- Leetcode - Balanced Binary Tree
- poj3461 Oulipo(KMP)
- MJRefresh代码分析
- 视差贴图(Parallax Mapping)