2017多校训练赛第二场 HDU 6051 (数论)——By alpc_wh

来源:互联网 发布:mac修容 编辑:程序博客网 时间:2024/06/05 03:18

If the starlight never fade

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 122    Accepted Submission(s): 65

Problem Description

We will give you a non-negative integer m and a prime number p.
And we define f(i) is the number of pair(x,y) that satisfies (x+y)ixi%p and 1xp1,1ym.
Now, you have to calculate the sum p1i=1if(i).
Maybe the sum is too big,so you only need to output the sum after mod 1e9+7.

Input

The first line contains only one integer T, which indicates the number of test cases.
For each test case, there are a integer m(1mp1) and a prime number p(2p1e9+7) on one line.

Output

For each test case, output one line "Case #x: y", where x is the case number (starting from 1) and y is the sum after mod1e9+7.

Sample Input

35 73 112 103

Sample Output

Case #1: 210Case #2: 390Case #3: 50388

Source

2017 Multi-University Training Contest - Team 2



        非常有意思的数论题,纯理论,推出结论后照抄公式计算即可。这里直接把我们学长的推导过程贴出来吧,不要盗走哦。——By alpc_wh。

                      

        两进Final、五次regional金牌……Orz……感谢大佬提供详尽题解……具体见代码,这么清楚了,我没什么好说的了:

#include<bits/stdc++.h>#define mod 1000000007#define LL long longusing namespace std;int phi(int k)//欧拉函数phi{    int i,s;    s = k;    for(i = 2;i * i <= k; i++)    {        if(k % i == 0) s = s / i * (i - 1);        while(k % i == 0) k /= i;    }    if(k > 1) s = s / k * (k - 1);    return s;}LL m,p,j;int main(){    int T_T,T;    cin>>T_T;T=T_T;    while(T_T--)    {        scanf("%I64d%I64d",&m,&p);        p--; LL ans=0;        int n=(int) sqrt(p);        for(LL i=1;i<=n;i++)        {            if (p%i) continue;            ans+=p/2ll*(i-1ll)*phi(p/i);            if (ans>=mod) ans%=mod;            if (i==1) continue; j=p/i;            ans+=p/2ll*(j-1ll)*phi(p/j);            if (ans>=mod) ans%=mod;        }        ans+=p*(p-1ll); ans%=mod;        printf("Case #%d: %I64d\n",T-T_T,ans*m%mod);    }    return 0;}

原创粉丝点击