又是一道疯狂TLE的题
比赛的思路基本没错,但缺少对时间的优化,只要优化了就ac了,所以没做出这题还是比较可惜的;
一开始我想的是找到所有的质数,然后让他们分别作为gcd的值,后来发现会有重复,就想着改用莫比乌斯反演和容斥定理;
#include <bits/stdc++.h>
#define N 100005
#define INF 1000000007
#define MOD 1000000007
using namespace std;
typedef long long ll;
bool vis[N];
int t,prime[N],cnt,n,Time,mu[N],a[N],f[N];
ll ans;
void init_mu()
{
memset(vis,0,sizeof(vis));
mu[1] = 1;
cnt = 0;
for(int i = 2;i < N;i++)
{
if(!vis[i])
{
prime[cnt++] = i;
mu[i] = -1;
}
for(int j = 0;j < cnt && i*prime[j] < N;j++)
{
vis[i*prime[j]] = 1;
if(i % prime[j]) mu[i*prime[j]] = -mu[i];
else
{
mu[i*prime[j]] = 0;
break;
}
}
}
}
ll ksm(ll x,ll y)
{
ll ans = 1;
while(y)
{
if(y & 1) ans = ans * x % MOD;
x = x * x % MOD;
y >>= 1;
}
return ans;
}
int main()
{
init_mu();
scanf("%d",&t);
while(t--)
{
ans = 0;
memset(f,0,sizeof(f));
scanf("%d",&n);
int Min = INF;
for(int i = 1;i <= n;i++)
{
scanf("%d",&a[i]);
Min = min(a[i],Min);
f[a[i]]++;
}
for(int i = 1;i <= n;i++) f[i] += f[i-1];
for(int i = 2;i <= Min;i++)
{
ll temp = 1;
for(int j = i;j <= n;j += i) temp = temp * ksm(j/i,f[min(j+i-1,n)] - f[j-1]) % MOD;
ans = (ans + temp*mu[i]*-1 + MOD) % MOD;
}
cout<<"Case #"<<++Time<<": "<<ans<<endl;
}
}
如果TLE,还是要多想优化的方法,就像多校1的B题那样。