luogu 4240 毒瘤之神的考验 (莫比乌斯反演)

题目大意:略

题面传送门

果然是一道神duliu题= =

出题人的题解传送门

出题人的题解还是讲得很明白的

1.关于$\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{m}\varphi (i,j)=\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{m}\frac{\varphi (i)\varphi (j)gcd(i,j)}{\varphi (gcd(i,j))}$的证明,lgl神犇提供了一种方法

假设现在$gcd(i,j)$中有一个质因子$p$,幂次是$k$,那么它对$\varphi (gcd(i,j))$的贡献就是$p^{k-1}(p-1)$

设$i$中$p$的幂次是$k_{1}$,$j$是$k_{2}$。则他们对$\varphi (i),\varphi (j)$的贡献分别是$p^{k_{1}-1}(p-1)$和$p^{k_{2}-1}(p-1)$,相乘得$p^{k_{1}+k_{2}-2}(p-1)^{2}$

而$p$对$\varphi (ij)$的贡献是$p^{k_{1}+k_{2}-1}(p-1)$,所以$\frac{p^{k}}{p^{k-1}(p-1)}=\frac{p}{p-1}$

$\frac{p}{p-1}*p^{k_{1}+k_{2}-2}(p-1)^{2}=p^{k_{1}+k_{2}-1}(p-1)$

而质因子间互不影响,因此得证

2.对于最后化简出来的式子$\sum\limits_{Q=1}^{n} \left ( \sum\limits_{d|Q}\frac{d}{\varphi (d)}\mu(\frac{Q}{d}) \right ) \left ( \sum\limits_{i=1}^{\left \lfloor \frac{n}{Q} \right \rfloor} \varphi (iQ) \right ) \left ( \sum\limits_{i=1}^{\left \lfloor \frac{m}{Q} \right \rfloor} \varphi (jQ) \right )$ 的处理

整除分块不能同时处理两个定义域不同的函数相乘!

所以要把第一个式子$\left ( \sum\limits_{d|Q}\frac{d}{\varphi (d)}\mu(\frac{Q}{d}) \right )$ 按照常规方法进行整除分块,第二个式子$\left ( \sum\limits_{i=1}^{\left \lfloor \frac{n}{Q} \right \rfloor} \varphi (iQ) \right ) $和$\left ( \sum\limits_{i=1}^{\left \lfloor \frac{m}{Q} \right \rfloor} \varphi (jQ) \right )$用官方题解的方法处理

蒟蒻用$vector$写的常数巨大

 1 #include <vector>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 #define N1 100010
 6 #define ll long long
 7 #define dd double
 8 using namespace std;
 9 
10 const int B=31;
11 const int maxn=100000;
12 const int jr=998244353;
13 
14 void exgcd(ll a,ll b,ll &x,ll &y)
15 {
16     if(!b){ x=1; y=0; return; }
17     exgcd(b,a%b,x,y); ll t=x; x=y; y=t-a/b*y; 
18 }
19 int mu[N1],phi[N1],use[N1],pr[N1],cnt;
20 int f[N1],G[N1][B+1][B+1];
21 vector<int>g[N1];
22 void init()
23 {
24     int i,j,Q,n; mu[1]=phi[1]=1;
25     for(i=2;i<=maxn;i++)
26     {
27         if(!use[i]){ pr[++cnt]=i; mu[i]=-1; phi[i]=i-1; }
28         for(j=1;j<=cnt&&i*pr[j]<=maxn;j++)
29         {
30             use[i*pr[j]]=1;
31             if(i%pr[j]){ mu[i*pr[j]]=-mu[i]; phi[i*pr[j]]=phi[i]*phi[pr[j]]; }
32             else{ phi[i*pr[j]]=phi[i]*pr[j]; break; }
33         }
34     }
35     int ans=0;ll inv,y;
36     for(Q=1;Q<=maxn;Q++)
37     {
38         ans=0;
39         for(i=1;i*Q<=maxn;i++)
40         {
41             ans=(phi[i*Q]+ans)%jr;
42             g[Q].push_back(ans);
43         }
44     }
45     for(i=1;i<=maxn;i++)
46     {
47         exgcd(phi[i],jr,inv,y); inv=(inv%jr+jr)%jr;
48         for(j=1;j*i<=maxn;j++)
49             f[i*j]=(1ll*i*inv%jr*mu[j]%jr+f[i*j]+jr)%jr;
50         //sf[i]=(sf[i-1]+f[i])%jr;
51     }
52     for(Q=1;Q<=maxn;Q++)
53     {
54         for(i=1;i<=B;i++) for(j=1;j<=B;j++)
55             G[Q][i][j]=(1ll*g[Q][i-1]*g[Q][j-1]%jr*f[Q]+G[Q-1][i][j])%jr;
56     }
57 }
58 int n,m,T;
59 
60 int main()
61 {
62     scanf("%d",&T);
63     init();
64     int i,j,la;ll ans=0;
65     while(T--)
66     {
67         scanf("%d%d",&n,&m); if(n>m) swap(n,m);
68         for(i=1,ans=0;i<=n&&m/i>B;i++)
69             ans=(ans+1ll*g[i][n/i-1]*g[i][m/i-1]%jr*f[i]%jr)%jr;
70         for(;i<=n;i=la+1)
71         {
72             la=min(n/(n/i),m/(m/i));
73             ans=(ans+G[la][n/i][m/i]-G[i-1][n/i][m/i]+jr)%jr;  
74         }
75         printf("%lld\n",ans);
76     }
77     return 0;
78 }

 

posted @ 2019-01-06 19:05  guapisolo  阅读(144)  评论(0编辑  收藏  举报