1 2 107
0
题意:
给出 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; }