题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6053
AC代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+100;
const ll mod=1e9+7;
int mu[maxn];
ll qpow(ll a,ll b,ll mo)
{
ll ans=1;
while(b > 0)
{
if(b&1)
{
ans=(ans*a)%mo;
}
a=a*a%mo;
b/=2;
}
return ans;
}
int vis[100005],prim[100005];
int cn=0;
void mobius(int n)
{
mu[1]=1;
for(int i=2; i<=n; i++)
{
if(!vis[i])
{
prim[++cn]=i;
mu[i]=-1;
}
for(int j=1; j<=cn && prim[j]*i<=n; j++)
{
vis[prim[j]*i]=1;
if(i%prim[j]==0)
{
mu[prim[j]*i]=0;
break;
}
else mu[i*prim[j]]=-mu[i];
}
}
}
int cnt[100005];
ll pre[maxn];
int main()
{
mobius(100003);
int t;
int Case=0;
cin>>t;
while(t--)
{
int n;
cin>>n;
memset(cnt,0,sizeof(cnt));
int maxx=0,minn=100005;
memset(pre,0,sizeof(pre));
int t;
ll ans1=1;
for(int i=1; i<=n; i++)
{
cin>>t;
maxx=max(t,maxx);
minn=min(t,minn);
cnt[t]++;
ans1=(ans1*(ll)t)%mod;
}
ll ans=0;
for(int i=1; i<=maxx; i++)
{
pre[i]=cnt[i]+pre[i-1];
}
for(int x=1; x<=minn; x++)
{
ll tmp=1;
if(mu[x]==0)
{
tmp=0;
}
else
{
int tt=maxx/x;
for(int i=1; i<=tt; i++)
{
int l=i*x-1;
int r=min((i+1)*x-1,maxx);
tmp=tmp*qpow(i,pre[r]-pre[l],mod)%mod;
}
tmp=((tmp*(ll)mu[x])%mod+mod)%mod;
}
ans=((ans+tmp)%mod +mod)%mod;
}
ans1=(((ans1-ans)%mod) + mod)%mod;//以后减法我一定先mod再+mod再mod
printf("Case #%d: %lld\n",++Case,ans1);
}
return 0;
}
我一定可以的!!!