#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <map>
#define INF 0x3f3f3f3f
#define rep0(i, n) for (int i = 0; i < n; i++)
#define rep1(i, n) for (int i = 1; i <= n; i++)
#define rep_0(i, n) for (int i = n - 1; i >= 0; i--)
#define rep_1(i, n) for (int i = n; i > 0; i--)
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
#define mem(x, y) memset(x, y, sizeof(x))
#define MAXN 100010
using namespace std;
typedef long long ll;
const ll mod = 1e9 + 7;
bool vis[MAXN];
int primes[MAXN];
int miu[MAXN], a[MAXN], n;
int calc(int limit)
{
memset(vis, false, sizeof(vis));
memset(miu, 0, sizeof(miu));
int tot = 0;
miu[1] = 1;
pre[1] = 1;
for(int i = 2; i <= limit; i++)
{
if(!vis[i])
{
primes[tot++] = i;
miu[i] = -1;
}
for(int j = 0; j < tot; j++)
{
int k = i * primes[j];
if(k > limit)
break;
vis[k] = true;
if(i % primes[j])
{
miu[k] = -miu[i];
}
else
break;
}
}
}
int mn, mx;
ll tot;
int sum[MAXN];
ll multi(ll a, int t)
{
ll ans = 1;
while (t)
{
if (t & 1)
{
ans = (ans * a) % mod;
}
a = (a * a) % mod;
t >>= 1;
}
return ans;
}
ll solve()
{
int last;
ll ans = tot;
for (int d = 2; d <= mn; d++)
{
if (!miu[d])
continue;
ll tmp = 1;
for (int i = 1; i <= mx / d; i++)
{
tmp = tmp * multi(i, sum[MIN(d * (i + 1), mx + 1) - 1] - sum[d * i - 1]) % mod; /**runtime error */
}
ans = (ans + (tmp * miu[d] + mod) % mod) % mod;
}
return ans;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
#endif // ONLINE_JUDGE
//calc(500);
int t, kase = 0;
calc(MAXN - 2);
scanf("%d", &t);
while (t--)
{
mem(sum, 0);
scanf("%d", &n);
mn = INF;
mx = 0;
tot = 1;
for (int i = 0; i < n; i++)
{
scanf("%d", a + i);
mn = MIN(mn, a[i]);
mx = MAX(mx, a[i]);
tot = (tot * a[i]) % mod;
sum[a[i]]++;
}
for (int i = mn; i < MAXN; i++)
sum[i] += sum[i - 1]; /**前缀维护*/
ll ans = (tot - solve() + mod) % mod;
printf("Case #%d: %lld\n", ++kase, ans);
}
return 0;
}
hdu6053_TrickGCD_莫比乌斯反演_快速幂优化_前缀和
猜你喜欢
转载自blog.csdn.net/Anna__1997/article/details/79807310
今日推荐
周排行