【BZOJ 3561】 DZY Loves Math VI

题目:

  给定正整数n,m。求
 

题解:

  水题有益身心健康。(博客园的辣鸡数学公式)

  其实到这我想强上伯努利数,然后发现$n^2$的伯努利数,emmmmmm

  发现这个式子可以算时间复杂度,emmmmm。积了个分发现时间复杂度很优秀啊(大概也就是$nlog$级别的)。

  所以直接算就好了。

  P.S.想卡卡常刷一个题榜rank1,emmmm发现自己没这个天赋。

代码:

 1 #define Troy
 2  
 3 #include "bits/stdc++.h"
 4  
 5 using namespace std;
 6  
 7 const int mod=1000000007,N=5e5+5;
 8  
 9 inline int powmod(int a,int b){
10     int ret=1;
11     while(b){
12         if(b&1) ret=ret*1ll*a%mod;
13         b>>=1;
14         a=a*1ll*a%mod;
15     }return ret;
16 }
17  
18 int prim[N],num,mu[N],vis[N],sum[N],ans,f[N];
19  
20 inline int calc(int n,int m,int t){
21     register int i,j;
22     int ret=0;
23     for (i=1;i<=m;++i){
24         f[i]=f[i]*1ll*i%mod;
25         vis[i]=mu[i]*(f[i]*1ll*f[i]%mod);
26         vis[i]+=vis[i-1];
27         vis[i]%=mod;
28         sum[i]=sum[i-1]+f[i];
29         sum[i]%=mod;
30     }
31     for (i=1;i<=n;i=j+1){
32         j=min(n/(n/i),m/(m/i));
33         ret=(ret+(vis[j]-vis[i-1])*1ll*sum[n/i]%mod*sum[m/i])%mod;
34     }
35     return ret;
36 }
37  
38 int main(){
39     int n,m;
40     scanf("%d%d",&n,&m);
41     if(n>m) swap(n,m);
42     register int i,j;
43     for(i=2,mu[1]=1;i<=n;++i){
44         if(!vis[i]) {
45             mu[i]=-1,prim[++num]=i;
46         }for(j=1;prim[j]*i<=n;++j){
47             vis[i*prim[j]]=true;
48             if(i%prim[j]==0)    {
49                 mu[i*prim[j]]=0;break;
50             }mu[i*prim[j]]=-mu[i];
51         }
52     }
53     for(i=1;i<=m;++i)   f[i]=1;
54     for(i=1;i<=n;++i){
55         ans=(ans+powmod(i,i)*1ll*calc(n/i,m/i,i))%mod;
56     }
57     printf("%d\n",ans);
58 }
59 

 

posted @ 2017-12-09 07:27  Troywar  阅读(422)  评论(0编辑  收藏  举报