[BZOJ3561] DZY Loves Math VI

(14.10.28改)

本来只想写BZOJ3739:DZY Loves Math VIII的,不过因为和VI有关系,而且也没别人写过VI的题解,那么写下。

 

不过我还不会插公式……

 

http://www.lydsy.com/JudgeOnline/problem.php?id=3561

 

想想还是要把代码放一下的,不然可能一辈子都不会写了= =

为什么那么像FancyCoder写的呢……因为这题本来就是他教我哒……读入优化快速筛甚至快速幂的模板都是他的= =

额Mobius反演系列问题的入门也是看Jcvb大爷blog学的……

= =

简要说下,设F(d,k)为正整数d次幂的前K项和。

然后化成∑(D=1...n)∑(d|D)d^d*μ(D/d)*F(d,n/d)*F(d,m/d)……

发现能预处理出F(d,n/d)和F(d,m/d)就好了……

然后我对杜教多项式求和的课件进行了艰苦卓绝的复习(学习)……当然失败了。

最后看Fancy代码……

暴力!

居然是暴力!

妈蛋……

简要的说……就是裸的不能裸暴力啊泥煤,预处理时间复杂度O(∑(n/d))=O(nlogn)。

 

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
#define rep(i,j,n) for(i=j;i<=n;i++)
template < class T> inline void read(T&x){ char c; for (c= getchar ();c< '0' ||c> '9' ;c= getchar ()); for (x=0;c>= '0' &&c<= '9' ;c= getchar ())x=x*10+c- '0' ;};
typedef long long ll;
const int N=500000;
const int mod=1000000007;
ll i,j,k,l,tt,d2,res,ans,d;
int P,Q,n,m;
ll s[N+10],t[N+10];
ll pow (ll a){ll ans=1,b=a; for (a%=mod;b;b>>=1,a=a*a%mod) if (b&1)ans=ans*a%mod; return ans;}
  
bool pd[N+1]; int u[N+1],p[N/5+1];
void pre(){
     pd[1]=1;u[1]=1;
     rep(i,2,N){
         if (!pd[i]){p[++p[0]]=i;u[i]=-1;}
         for ( int j=1,mul;j<=p[0]&&(mul=i*p[j])<=N;j++){
             pd[mul]=1;
             if (i%p[j]==0){u[mul]=0; break ;}
             u[mul]=-u[i];
         }
     }
}
int main()
{
     read(n);read(m);
     if (n>m)swap(n,m);
     pre();
     rep(i,1,m)t[i]=1;
     rep(d,1,n){
     Q=m/d;
         rep(i,1,Q)t[i]=t[i]*i%mod;
         rep(i,1,Q)s[i]=(s[i-1]+t[i])%mod;
         res=0;P=n/d;
         rep(d2,1,P) if (u[d2]){
             tt=t[d2]*t[d2]%mod*s[P/d2]%mod*s[Q/d2]%mod;
             res+=tt*u[d2];
         }
         res%=mod;
         ans=(ans+res* pow (d))%mod;
     }
     printf ( "%lld\n" ,ans);
     return 0;
}

你可能感兴趣的:(Math)