题解:
主要是原根的幂表示[1, p - 1],
然后转换
hint里的公式:
找了一篇证明:http://blog.youkuaiyun.com/Clove_unique/article/details/53152473
代码:
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
const ll mod = 1e9 + 7;
ll m, p;
ll getPhi(ll x)
{
ll ret = x;
for(ll i = 2; i * i <= x; ++i)
{
if(x % i == 0)
{
while(x % i == 0) x /= i;
ret -= ret / i;
}
}
if(x > 1) ret -= ret / x;
return ret;
}
ll get(int n, int fac)
{
return (ll)fac * fac % mod * (((ll)n * getPhi(n) + (n == 1)) / 2) % mod;
}
int cal(int x)
{
int ret = 0;
for(int i = 1; (ll)i * i <= x; ++i)
{
if(x % i == 0)
{
ret = (ret + get(x / i, i)) % mod;
if(i != x / i) ret = (ret + get(i, x / i)) % mod;
}
}
ret -= ((ll)x * (x + 1) / 2) % mod;
ret = (ret % mod + mod) % mod;
return ret;
}
int main()
{
int t;
scanf("%d", &t);
int kas = 0;
while(t--)
{
scanf("%lld%lld", &m, &p);
ll res = cal(p - 1);
printf("Case #%d: %d\n", ++kas, (res * m) % mod);
}
return 0;
}