bzoj 3560


╮(╯▽╰)╭数学渣就是被虐。。。

http://blog.csdn.net/popoqqq/article/details/42739963
其实推导过程中用了生成函数。


#include
#include
#include
#include
#include
#include
#include
#include
const int MAXN = 1e5 + 5, Mod = 1e9 + 7, logM = 32;
double eps = 1e-8;

int n;int a[MAXN] = {0};
long long ans = 1;
struct ThePrime
{
    int p,k;
}pn[MAXN<<4] = {0};

int tot = 0;
void primediv(int x)
{
    int lmt = (int)(sqrt(x)+eps);
    for(int i = 2 ; i <= lmt ; i++)
      if(x%i == 0)
      {
         pn[++tot].p = i;
         while(x%i == 0)
            x /= i,pn[tot].k++;
      }
    if(x!=1)pn[++tot].p = x,pn[tot].k = 1;  
}
long long Powermod(long long x,int y)  
{  
    long long ret = 1;  
    while(y)  
    {  
        if(y&1) ret = (ret*x)%Mod;  
        x = x*x%Mod; y>>=1;  
    }  
    return ret;  
}  
void Work(int st,int ed)  
{  
    static long long sum[logM];  
    long long p = pn[st].p , val = 1;  

    sum[0]=1;  
    for(int i = 1; i <= pn[ed].k ; i++)sum[i] = sum[i-1]* p%Mod;  
    for(int i = 1; i <= pn[ed].k ; i++){sum[i] += sum[i-1],sum[i] %= Mod;}  
    for(int i = st;i <= ed; i++)val *= sum[pn[i].k] , val %= Mod;  

    val = (val - 1 + Mod) %Mod;
    val *= Powermod(p,Mod-2), val%=Mod;  
    val *= p-1, val =(val + 1)%Mod;  
    ans *= val , ans %= Mod;  
}  
bool cmp(const ThePrime &a, const ThePrime &b){return (a.p < b.p)||(a.p == b.p && a.k < b.k);}
int main()
{
#ifndef ONLINE_JUDGE    
     freopen("bzoj3560.in","r",stdin);
     freopen("bzoj3560.out","w",stdout);    
#endif  

     scanf("%d",&n);
     for(int i = 1; i<= n;i++)
       scanf("%d",&a[i]);
     for(int i = 1; i<= n;i++)
       primediv(a[i]);

     std::sort(pn + 1, pn + tot + 1,cmp);   

     pn[tot+1].p = 1;  
     for(int i = 1,st = 1; i <= tot ; i++)
        if(pn[i].p != pn[i+1].p)
           {Work(st,i); st = i+1;}

     std::cout << ans;

#ifndef ONLINE_JUDGE    
     fclose(stdin);
     fclose(stdout);
#endif   
     return 0;
}

你可能感兴趣的:(bzoj)