【BZOJ 3560】DZY loves Math V

i1|a1i2|a2...in|anϕ(i1i2..in)

设共有质因子 tot 个,第 i 个质因子在第 j 个数中指数为 kij
ans=Πtoti=1ji1=0ki1ji2=0ki2...jin=0kinϕ(primenp=1jipi)

=Πtoti=1((Πnj=1pij=0kijprimepiji)1)primei1primei+1

前缀和维护一下 primeji 即可

#include
#include
#include
#include
#include
#define p 1000000007
using namespace std;
struct hp{
    long long pi,ki;
    bool operator < (const hp &x) const
      {return (pix.ki);}
}prime[1001001];
int a[100001];
long long mi[35];
int tot,n;
long long ans;
long long power(long long a,long long b)
{
    long long t;
    if (b==0) return 1;
    if (b==1) return a;
    t=power(a,b/2);
    if (b%2==0) return t*t%p;
    else return a*t%p*t%p;
}
int main()
{
    int i,x,j,m; long long t,tp;
    scanf("%d",&n);
    for (i=1;i<=n;++i)
      scanf("%d",&a[i]); 
    for (i=1;i<=n;++i)
      {
        x=a[i]; m=sqrt(x+0.5);
        for (j=2;j<=m;++j)
          if (x%j==0)
            {
              prime[++tot].pi=(long long)j;
              while (x%j==0)
                {prime[tot].ki++; x/=j;}
            }
        if (x!=1)
          {prime[++tot].pi=(long long)x; prime[tot].ki=(long long)1;}
      }
    sort(prime+1,prime+tot+1); 
    ans=(long long)1; t=1;
    for (i=1;i<=tot;++i)
      {
        if (prime[i].pi!=prime[i-1].pi)
          {
            if (i!=1) ans=ans*(((t-1)*((prime[i-1].pi-1+p)%p)%p*power(prime[i-1].pi,p-2)%p+1)%p)%p;
            t=1;
            mi[0]=1; tp=(long long)1;
            for (j=1;j<=prime[i].ki;++j)
              {
                tp=(tp*prime[i].pi)%p;
                mi[j]=(mi[j-1]+tp)%p;
              }
          }
        t=(t*mi[prime[i].ki])%p;
      }
    ans=ans*((((t+p-1)%p)*((prime[tot].pi-1+p)%p)%p*power(prime[tot].pi,p-2)%p+1)%p)%p;
    printf("%lld\n",ans);
}

你可能感兴趣的:(数论)