# 莫比乌斯反演小结

$$f(n)=\sum _{d|n}F(d) \mu(\frac{n}{d})$$

$$f(n)=\sum _{n|d} F(d)\mu(\frac{d}{n})$$

$\mu \otimes 1 = e$，也即$\sum _{d|n} \mu(d)=[n==1]$

…………板子题就不放了，每道题都挺水的

1.bzoj3529

 1 #include <cstdio>
2 #include <cstring>
3 #include <algorithm>
4 using namespace std;
5 typedef long long LL;
6 const int N=100010;
7 const unsigned int inf=0x7fffffff;
8 bool vis[N+10];int tot;
9 unsigned int prime[N],sumd[N+10];
10 unsigned int tmp1[N+10],tmp2[N+10],mu[N+10],p[N+10];
11 struct node{unsigned int ans,id,n,m,a;}q[20010];
12 inline bool mt1(const node &a,const node &b){return a.a<b.a;}
13 inline bool mt2(const int &a,const int &b){return sumd[a]<sumd[b];}
14 inline bool mt3(const node &a,const node &b){return a.id<b.id;}
15 inline void intn()
16 {
17     int k;mu[1]=sumd[1]=1;
18     for(int i=2;i<=N;i++)
19     {
20         if(!vis[i])
21         {
22             prime[++tot]=tmp2[i]=i;
23             sumd[i]=tmp1[i]=i+1,mu[i]=-1;
24         }
25         for(int j=1;j<=tot&&(k=i*prime[j])<=N;j++)
26         {
27             vis[k]=1;
28             if(i%prime[j]==0)
29             {
30                 tmp2[k]=tmp2[i]*prime[j],tmp1[k]=tmp1[i]+tmp2[k];
31                 sumd[k]=sumd[i]/tmp1[i]*tmp1[k];
32                 mu[k]=0;break;
33             }
34             sumd[k]=sumd[i]*sumd[prime[j]];
35             tmp1[k]=1+prime[j];tmp2[k]=prime[j];
36             mu[k]=-mu[i];
37         }
38     }
39     for(int i=1;i<=N;i++)p[i]=i;
40     sort(p+1,p+N+1,mt2);
41 }
42 unsigned int bit[N+10];
43 inline int lowbit(int a){return a&-a;}
44 inline void add(int pos,unsigned int val){while(pos<=N)bit[pos]+=val,pos+=lowbit(pos);}
45 inline unsigned int query(int pos)
46     {unsigned int ret=0;while(pos)ret+=bit[pos],pos-=lowbit(pos);return ret;}
47 inline unsigned int calc(unsigned int n,unsigned int m)
48 {
49     if(n>m)swap(n,m);
50     unsigned int ret=0,last;
51     for(unsigned int i=1;i<=n;i=last+1)
52     {
53         last=min(n/(n/i),m/(m/i));
54         ret+=(n/i)*(m/i)*(query(last)-query(i-1));
55     }
56     return ret;
57 }
58 int main()
59 {
60     intn();int top=1,t;scanf("%d",&t);
61     for(int i=1;i<=t;i++)
62         q[i].id=i,scanf("%d%d%d",&q[i].n,&q[i].m,&q[i].a);
63     sort(q+1,q+t+1,mt1);
64     for(int i=1;i<=t;i++)
65     {
66         while(top<=N&&sumd[p[top]]<=q[i].a)
67         {
68             for(int k=1;k*p[top]<=N;k++)
70             top++;
71         }
72         q[i].ans=calc(q[i].n,q[i].m);
73     }
74     sort(q+1,q+t+1,mt3);
75     for(int i=1;i<=t;i++)
76         printf("%d\n",q[i].ans&inf);
77 }
bzoj3529

2.bzoj3309

$ans=\sum _{i=1} ^{n} \sum _{j=1} ^{m} f((i,j))$

$=\sum _{d=1} ^{n} f(d)\sum _{i=1} ^{n} \sum _{j=1} ^{m} [(i,j)==d]$

$=\sum _{d=1} ^{n} f(d)\sum _{i=1} ^{\left \lfloor \frac {n}{d} \right \rfloor } \sum _{j=1} ^{\left \lfloor \frac {m}{d} \right \rfloor } [(i,j)==1]$

$=\sum _{d=1} ^{n} f(d) \sum _{g=1} ^{ \left \lfloor \frac {n}{d} \right \rfloor } \mu(g) \left \lfloor \frac {n}{dg} \right \rfloor \left \lfloor \frac {m}{dg} \right \rfloor$

$\sum _{T=1} ^{n} \left \lfloor \frac {n}{T} \right \rfloor \left \lfloor \frac {m}{T} \right \rfloor \sum _{d|T}f(d)\mu(\frac{T}{d})$

 1 #include <cstdio>
2 #include <cstring>
3 using namespace std;
4 #define N 10000010
5 #define K 10000000
6 #define LL long long
7 char B[1<<15],*S=B,*T=B;
10 {
11     int x=0;register char c=getc;
12     while(c<'0'||c>'9')c=getc;
13     while(c>='0'&&c<='9')x=10*x+(c^48),c=getc;
14     return x;
15 }
16 int prime[K/10],tot,vis[N];
17 int mincnt[N],g[N],ppow[N];
18 inline void intn()
19 {
20     register int i,j,tmp;
21     for(i=2;i<=K;++i)
22     {
23         if(!vis[i])prime[++tot]=i,ppow[i]=mincnt[i]=g[i]=1;
24         for(j=1;j<=tot&&(tmp=i*prime[j])<=K;++j)
25         {
26             vis[tmp]=1;
27             if(i%prime[j]==0)
28             {
29                 mincnt[tmp]=mincnt[i]+1,ppow[tmp]=ppow[i];
30                 if(1==ppow[tmp])g[tmp]=1;
31                 else g[tmp]=(mincnt[ppow[tmp]]==mincnt[tmp])?-g[ppow[tmp]]:0;
32                 break;
33             }
34             mincnt[tmp]=1,ppow[tmp]=i,
35             g[tmp]=(mincnt[i]==1)?-g[i]:0;
36         }
37     }
38     for(i=1;i<=K;++i)g[i]+=g[i-1];
39 }
40 inline int min(int a,int b){return a<b?a:b;}
41 int main()
42 {
43     // freopen("Ark.in","r",stdin);
44     register int t,n,m,i,j;
46     while(t--)
47     {
49         if(n>m)n^=m,m^=n,n^=m;
50         for(i=1,ans=0;i<=n;i=j+1)
51             j=min(n/(n/i),m/(m/i)),ans+=(n/i)*1ll*(m/i)*(g[j]-g[i-1]);
52         printf("%lld\n",ans);
53     }
54 }
bzoj3309

3.bzoj4816

$\prod_{d=1}^{n} fibo(d) ^ { \sum_{g=1} ^ { \left \lfloor \frac{n}{d}\right \rfloor } \mu(g) \left \lfloor \frac{n}{dg}\right \rfloor\left \lfloor \frac{m}{dg}\right \rfloor }$

$\prod_{T=1}^{n} ( \prod_{d|t} fibo(d) ^ { \mu( \frac{T}{d} ) } ) ^{\left \lfloor \frac{n}{dg}\right \rfloor \left \lfloor \frac{m}{dg}\right \rfloor}$

 1 #include <cstdio>
2 #include <cstring>
3 using namespace std;
4 #define N 1000010
5 #define K 1000000
6 #define LL long long
7 #define mod 1000000007
8 char B[1<<15],*S=B,*T=B;
11 {
12     int x=0;register char c=getc;
13     while(c<'0'||c>'9')c=getc;
14     while(c>='0'&&c<='9')x=10*x+(c^48),c=getc;
15     return x;
16 }
17 inline LL quick_mod(LL di,LL mi)
18 {
19     LL ans=1;
20     for(di%=mod;mi;mi>>=1,di=di*di%mod)
21         if(mi&1)ans=ans*di%mod;
22     return ans;
23 }
24 LL f[N],g[N],invf[N],invg[N],h[N],x[N],invx[N];
25 int prime[N/10],tot,vis[N],mu[N];
26 inline void intn()
27 {
28     register int i,j,tmp;
29     for(f[0]=0,f[1]=g[1]=1,i=2;i<=K;++i)
30         f[i]=(f[i-1]+f[i-2])%mod,g[i]=g[i-1]*f[i]%mod;
31     for(invg[K]=quick_mod(g[K],mod-2),i=K;i;--i)
32         h[i]=1,invg[i-1]=invg[i]*f[i]%mod,invf[i]=invg[i]*g[i-1]%mod;
33     for(mu[1]=1,i=2;i<=K;++i)
34     {
35         if(!vis[i])prime[++tot]=i,mu[i]=-1;
36         for(j=1;j<=tot&&(tmp=prime[j]*i)<=K;++j)
37         {
38             vis[tmp]=1;
39             if(i%prime[j]==0){mu[tmp]=0;break;}
40             mu[tmp]=-mu[i];
41         }
42     }
43     for(i=2;i<=K;++i)
44         for(j=1;(tmp=i*j)<=K;++j)
45             if(mu[j]==1)h[tmp]=h[tmp]*f[i]%mod;
46             else if(mu[j]==-1)h[tmp]=h[tmp]*invf[i]%mod;
47     for(x[1]=h[1]=1,i=2;i<=K;++i)x[i]=x[i-1]*h[i]%mod;
48     invx[K]=quick_mod(x[K],mod-2);
49     for(i=K;i;--i)invx[i-1]=invx[i]*h[i]%mod;
50 }
51 inline int min(int a,int b){return a<b?a:b;}
52 int main()
53 {
54     register int i,j,t,n,m;
56     while(t--)
57     {
59         if(n>m)n^=m,m^=n,n^=m;
60         for(ans=i=1;i<=n;i=j+1)
61         {
62             j=min(n/(n/i),m/(m/i)),
63             ans=ans*quick_mod( x[j]*invx[i-1]%mod , (n/i)*1ll*(m/i)%(mod-1) )%mod;
64         }
65         printf("%lld\n",ans);
66     }
67 }
bzoj4816

4.bzoj3601

……让人无法形容的恐惧

 1 #include <cstdio>
2 #include <cstring>
3 using namespace std;
4 #define LL long long
5 #define N 1010
6 #define D 110
7 #define mod 1000000007
8 char cB[1<<15],*S=cB,*T=cB;
11 {
12     int x=0;register char c=getc;
13     while(c<'0'||c>'9')c=getc;
14     while(c>='0'&&c<='9')x=10*x+(c^48),c=getc;
15     return x;
16 }
17 inline int quick_mod(int di,int mi)
18 {
19     if(mi<0)return quick_mod(quick_mod(di,mod-2),-mi);
20     int ret=1;
21     for(di%=mod;mi;mi>>=1,di=(LL)di*di%mod)
22         if(mi&1)ret=(LL)ret*di%mod;
23     return ret;
24 }
25 int d,w,p[N],A,a[N];
26 int fac[D],inv[D],invf[D],B[D];
27 #define C(i,j) ((LL)fac[i]*invf[j]%mod*invf[i-j]%mod)
28 int main()
29 {
30     // freopen("Ark.in","r",stdin);
31     register int i,j,k,ans,sum,tot=1;
33     for(i=1;i<=w;++i)
35     for(fac[0]=fac[1]=1,i=2;i<=d+2;++i)fac[i]=(LL)fac[i-1]*i%mod;
36     for(inv[0]=inv[1]=1,i=2;i<=d+2;++i)inv[i]=(LL)(mod-mod/i)*inv[mod%i]%mod;
37     for(invf[0]=invf[1]=1,i=2;i<=d+2;++i)invf[i]=(LL)invf[i-1]*inv[i]%mod;
38     for(B[0]=1,i=1;i<=d+2;++i)
39     {
40         for(B[i]=0,j=0;j<i;++j)
41             B[i]=(B[i]+(LL)C(i+1,j)*B[j]%mod)%mod;
42         B[i]=((LL)-B[i]*inv[i+1]%mod+mod)%mod;
43     }
44     for(ans=0,i=1;i<=d+1;++i)
45     {
46         A=((LL)( ((d+1-i)&1)?-1:1 )*C(d+1,i)*B[d+1-i]%mod*inv[d+1]%mod+mod)%mod;
47         if(A==0)continue;
48         // printf("%d\n",A);
49         for(sum=quick_mod(tot,i),j=1;j<=w;++j)
50             sum=(LL)sum*( mod+ 1ll- quick_mod(p[j],d-i) ) %mod;
51         // printf("sum=%d\n",sum);
52         ans=(ans+(LL)A*sum%mod)%mod;
53     }
54     printf("%d\n",(ans%mod+mod)%mod);
55 }
bzoj3601

5.bzoj4174

1.$\left \lfloor \frac{nk}{m}\right \rfloor = \frac{nk-nk\%m}{m} = \frac{nk}{m}-\frac{nk\%m}{m}$

2.这道题大量的运用了把问题拆分再分段处理的思想……这样的确可以简化问题，这种不行就拆分的转换是很巧妙的

 1 #include <cstdio>
2 #include <cstring>
3 #include <cmath>
4 using namespace std;
5 #define mod 998244353
6 #define N 500010
7 #define K 500000
8 #define LL long long
9 #define db double
10 int n,m,x;double tmp;
11 //把整除拆成
12 inline int Sum(int x){return ((LL)x*(x+1)>>1)%mod;}
13 int prime[N/10],tot,vis[N],mu[N];
14 inline void intn(int m)
15 {
16     register int i,j,tmp;
17     for(mu[1]=1,i=2;i<=m;++i)
18     {
19         if(!vis[i])prime[++tot]=i,mu[i]=-1;
20         for(j=1;j<=tot&&(tmp=i*prime[j])<=m;++j)
21         {
22             vis[tmp]=1;
23             if(i%prime[j]==0){mu[tmp]=0;break;}
24             mu[tmp]=-mu[i];
25         }
26     }
27     for(i=2;i<=m;++i)mu[i]+=mu[i-1];
28 }
29 inline int min(int a,int b){return a<b?a:b;}
30 inline int calc(int a,int b)
31 {
32     register int i,j,ret=0;
33     if(a>b)a^=b,b^=a,a^=b;
34     for(i=1;i<=a;i=j+1)
35         j=min(a/(a/i),b/(b/i)),ret=(ret+(LL)(mu[j]-mu[i-1])*(a/i)*(b/i)%mod)%mod;
36     return ret;
37 }
38 int main()
39 {
40     // freopen("Ark.in","r",stdin);
41     register int i,j,k;
42     scanf("%d%d%lf",&n,&m,&tmp);x=tmp;
43     int ans=((LL)Sum(n)*Sum(m)-(LL)Sum(n)*m-(LL)Sum(m)*n)%mod;
44     if(n>m)n^=m,m^=n,n^=m;intn(n);
45     for(i=1;i<=n;++i)
46         ans=(ans+(LL)(2*i*(x/i)+i)*calc(n/i,m/i)%mod)%mod;
47     ans=(ans+mod)%mod,printf("%lld\n",(LL)ans*499122177%mod);
48 }
bzoj4174
$xyz117$推荐的题目，据说是好题，现在还没有做……等再回头的时候做吧

posted @ 2018-01-22 21:46 LadyLex 阅读(...) 评论(...) 编辑 收藏