之前不知道莫比乌斯反演,看了一波,然后有些许理解,这个题其实就是使用了莫比乌斯函数U的定义,详细的解题报告这里说的比较清楚
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<string>
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<cstring>
#define clr(x) memset(x,0,sizeof(x))
using namespace std;
#define LL long long
const int N = 100005;
const int MOD = 1e9+7;
bool vis[N];
int U[N];
int prime[N];
int cnt;
void GetMU()
{
memset(vis,0,sizeof(vis));
U[1] = 1;
cnt = 0;
for(int i=2; i<N; i++)
{
if(!vis[i])
{
prime[cnt++] = i;
U[i] = -1;
}
for(int j=0; j<cnt&&i*prime[j]<N; j++)
{
vis[i*prime[j]] = 1;
if(i%prime[j]) U[i*prime[j]] = -U[i];
else
{
U[i*prime[j]] = 0;
break;
}
}
}
}
LL quickPow(LL a,LL b)
{
LL ans = 1;
while(b)
{
if(b&1)
{
ans *= a;
ans %= MOD;
}
a*=a;
a %= MOD;
b>>=1;
}
return ans;
}
int dat[N];
int mi,ma;
int main()
{
int t;
GetMU();
scanf("%d",&t);
int _case = 0;
while(t--)
{
int n;
mi = 9999999;
ma = 0;
scanf("%d",&n);
clr(dat);
for(int i = 0;i<n;i++)
{
int temp;
scanf("%d",&temp);
dat[temp]++;
mi = min(mi,temp);
ma = max(ma,temp);
}
for(int i = 1;i<=ma;i++)dat[i] += dat[i-1];
LL ans = 0;
for(int i = 2;i<=mi;i++)
{
LL cur = -U[i];
for(int j = 1;j*i<=ma;j++)
{
int l = i*j;
int r = min(i*j+i-1,ma);
cur = cur*(quickPow(j,dat[r]-dat[l-1]))%MOD;
}
ans += cur;
ans = (ans+MOD)%MOD;
}
printf("Case #%d: %lld\n",++_case,ans);
}
return 0;
}