zoukankan      html  css  js  c++  java
  • 莫比乌斯反演 刷题记录

    BZOJ1101: [POI2007]Zap

    • 题意:对于给定的整数a,b和d,求有多少正整数对x,y,满足x<=a,y<=b,并且gcd(x,y)=d
    • 直接求有多少正整数对x,y,gcd(x,y)=d比较难求,而且询问有50000个,


    • egin{gather*}
      要求 f( n) = sum olimits ^{ b}_{ y=1} sum olimits ^{ a}_{ x=1} [ gcd( x,y) =n ]\
      \
      则 F( n) =sum olimits ^{ b}_{ y=1}sum olimits ^{ a}_{ x=1}sum olimits _{ n|gcd( x,y)} 1\
      \
      因为 sum olimits _{ n|gcd( x,y)} 1=sum olimits _{ n|d} [ gcd( x,y) =d ]\
      \
      F( n) = sum olimits _{ n|d} f( d)\
      \
      然后就是莫比乌斯反演辣\
      \
      end{gather*}

    • 代码:
    •  1 #include <bits/stdc++.h>
       2 #define nmax 50010
       3  
       4 using namespace std;
       5 int pri[nmax],table[nmax],mu[nmax];
       6 int cp=-1;
       7  
       8 void getmu(){
       9     for (int i=2; i<nmax; i++) {
      10         if(table[i]==0) { pri[++cp]=i; mu[i]=-1; }
      11         for (int j=0; j<=cp; j++) {
      12             int t=i*pri[j];
      13             if(t>=nmax) break;
      14             table[t]=1;
      15             if(i%pri[j]==0) {mu[t]=0; break;}
      16             mu[t]=mu[i]*(-1);
      17         }
      18     }
      19     mu[1]=1;
      20     for (int i=0; i<nmax; i++) mu[i]+=mu[i-1];
      21 }
      22  
      23 int main(){
      24     int n,a,b,d;
      25     getmu();
      26      cin>>n;
      27     while(n--){
      28         scanf("%d%d%d",&a,&b,&d);
      29         if(a>b) swap(a,b);
      30         a/=d;
      31         b/=d;
      32         //分块算答案
      33         int last,ans=0;
      34         for (int i=1; i<=a; i=last+1){
      35             last=min( a/(a/i) , b/(b/i) );
      36             ans+=(a/i)*(b/i)*(mu[last]-mu[i-1]);
      37         }
      38         printf("%d
      ",ans);
      39     }
      40     return 0;
      41 }
      》w《

    POJ3904 Sky Code

    • 给出一堆数,让你找有多少个四元组(a,b,c,d),满足a,b,c,d的gcd为1
    • 比较裸的莫比乌斯反演,跟上面一样
    • F(n) 为满足n|gcd(a,b,c,d)的四元组个数,f(n)为满足gcd(a,b,c,d)=1的四元组个数
    •  于是这样
      egin{equation*}
      F( n) =sumlimits _{n|d} f( d)
      end{equation*}
    • 于是就可以根据公式反演了
    • 代码:
       1 #include <algorithm>
       2 #include <cstring>
       3 #include <iostream>
       4 #include <cstdio>
       5 #define nmax 10010
       6 
       7 using namespace std;
       8 typedef long long ll;
       9 int n,minx,cp=0;
      10 int t1[nmax]={0},in[nmax],mu[nmax],t3[nmax],pri[nmax];
      11 ll c[nmax][5]={0};
      12 ll ans;
      13 
      14 void getmu(){
      15     for (int i=2; i<nmax; i++) {
      16         if(t3[i]==0) { pri[++cp]=i; mu[i]=-1; }
      17         for (int j=1; j<=cp; j++) {
      18             int tx=i*pri[j];
      19             if(tx>nmax) break;
      20             t3[tx]=1;
      21             if(i%pri[j]==0) break;
      22             mu[tx]=mu[i]*(-1);
      23         }
      24     }
      25     mu[1]=1;
      26 }
      27 
      28 int main(){
      29     //组合数的表 c
      30     for (ll i=1; i<nmax; i++) c[i][1]=i;
      31     for (ll i=2; i<=4; i++) c[i][i]=1;
      32     for (ll j=2; j<=4; j++) for (ll i=j+1; i<nmax; i++) c[i][j]=c[i-1][j]+c[i-1][j-1];
      33     //莫比乌斯函数的表 mu
      34     getmu();
      35     while(scanf("%d",&n)!=EOF){
      36         memset(t1,0,sizeof(t1));
      37         ans=0;
      38         minx=nmax*10;
      39         for (int i=0; i<n; i++) { scanf("%d",&in[i]); minx=min(minx,in[i]); }
      40         //t1[i]有多少个数是i的倍数
      41         for (int i=0; i<n; i++) for (int j=1; j*j<=in[i]; j++) {
      42             if(in[i]%j==0) {
      43                 t1[j]++;
      44                 if( j != in[i]/j ) t1[in[i]/j]++;
      45             }
      46         }
      47 
      48         //反演部分
      49         for (int i=1; i<nmax; i++) ans+=mu[i]*c[ t1[i] ][4];
      50         printf("%lld
      ",ans);
      51     }
      52     return 0;
      53 }
      呜呼~
  • 相关阅读:
    Java突击学习 Day2 Part1
    Java突击学习 Day1
    SQL Server笔试准备 Day2
    SQL Server笔试准备 Day1
    .NET/C# 各版本变化及衍生知识点 C# 6.0
    .NET/C# 各版本变化及衍生知识点 C# 3.0/4.0/5.0
    .NET理论知识 笔试准备 Day3
    CSS---!important
    CSS---弹性布局
    HTML--meta标签
  • 原文地址:https://www.cnblogs.com/jiecaoer/p/11586397.html
Copyright © 2011-2022 走看看