bzoj 3560

来源:互联网 发布:ubuntu安装交叉编译器 编辑:程序博客网 时间:2024/06/06 02:14

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

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


#include<map>#include<string>#include<cstdio>#include<cstdlib>#include<cstring>#include<cmath>#include<iostream>#include<algorithm>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;}
0 0