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

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 1≤xp−1,1≤ym.
Now, you have to calculate the sum ∑p−1i=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(1≤mp−1) and a prime number p(2≤p≤1e9+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

 

 

3 5 7 3 11 2 103

 

Sample Output

 

 

Case #1: 210 Case #2: 390 Case #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 long
using 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;
}

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值