莫比乌斯

今年的多校比赛,莫比乌斯反演的题目经常出现,但是我们队对于这种题可以说是直接放掉,不是因为没学过,多少了解一些,但是也只是皮毛,导致根本就做不出来,其实想一想,其实次数多了,就可以看出原因了,没有过总结,没有过思考,昨天心血来潮,好好的看了一下莫比乌斯反演,有一点感悟!

  • 什么是莫比乌斯反演

...

可以通过​ 反向推导出 ​

...

公式:

其中 即为莫比乌斯函数。

也可以如下定义:

  • 分解质因数,无不相同,则

  • 其他为0

性质:积性函数

莫比乌斯(容斥的优化)——我的理解

怎么求莫比乌斯函数?

  • 类似于筛素数的方案,O(nlogn),一般足够了。

  • 级别,无法预处理出1~n的莫比乌斯表,利用因式分解,讨论因子的拿法(类似压状),O(sqrt(n))

栗子:

//求莫比乌斯函数 O(nlogn)
void getMu() {
   for(int i = 1; i < maxn; i++) {
       int target = i == 1 ? 1 : 0;
       int delta = target - mu[i];
       mu[i] = delta;

       for(int j = i + i ; j < maxn; j+=i)
           mu[j] +=delta;
  }
}
// n 的 约数的莫比乌斯函数值map形式返回 O(sqrt(n))
map<int,int> moebius(int n) {
   map<int,int> res;
   vector<int> primes;

   //枚举n的质数
   for(int i = 2; i*i <= n; i++) {
       if(n%i==0) {
           primes.push_back(i);
           while(n%i==0) n/=i;
      }
  }
   if(n!=1) primes.push_back(n);

   int m = primes.size();
   //不超过n的约数个数 次
   for(int i = 0; i < (1<<m); i++) {
       int mu = 1,d = 1;
       for(int j = 0; j < m; j++) {
           if(i>>j&1) {
               mu*=-1;
               d*=primes[j];
          }
      }
       res[d] = mu;
  }
   return res;
}

例题一:

分析:总共26^n,根据容斥,枚举最短循环节d,减去26^d,根据莫比乌斯函数来容斥优化。注意数据范围极大!

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

// n 的 约数的莫比乌斯函数值map形式返回 O(sqrt(n))
map<int,int> moebius(int n) {
   map<int,int> res;
   vector<int> primes;

   //枚举n的质数
   for(int i = 2; i*i <= n; i++) {
       if(n%i==0) {
           primes.push_back(i);
           while(n%i==0) n/=i;
      }
  }
   if(n!=1) primes.push_back(n);

   int m = primes.size();
   //不超过n的约数个数 次
   for(int i = 0; i < (1<<m); i++) {
       int mu = 1,d = 1;
       for(int j = 0; j < m; j++) {
           if(i>>j&1) {
               mu*=-1;
               d*=primes[j];
          }
      }
       res[d] = mu;
  }
   return res;
}

const int MOD = 10009;

int n;

//快速幂取模 a^b % mod;
ll pow_mod(ll a,ll b) {
   if(b==0) return 1%MOD;
   int temp = pow_mod(a,b>>1);

   temp = temp*temp%MOD;    if(b&1) temp = (ll)temp*a%MOD;    return temp;}​void solve() {    ll res = 0;    map<int,int> mu = moebius(n);    for(auto it = mu.begin(); it != mu.end(); it++) {        //printf("%d %d\n",it->first,it->second);        res += (ll)it->second*pow_mod(26,n/it->first);        res = (res%MOD + MOD) % MOD;   }    printf("%I64d\n",res);}​int main(){    scanf("%d",&n);    solve();    return 0;}

例题二:

分析:

注意:(1,3),(3,1)相同。

先考虑不同的情况:

即:两个区间内互质的对数,同理:总共 对,减去不符合情况的对数,枚举gcd,就有 * 对,然后用莫比乌斯来容斥。

怎么解决(1,3)(3,1)相同的情况呢?

还是容斥!!!

减去较小区间做一遍上述操作的一半。

#include <bits/stdc++.h>

using namespace std;

const int maxn = 1<<20;
int mu[maxn];


//求莫比乌斯函数
void getMu() {
   for(int i = 1; i < maxn; i++) {
       int target = i == 1 ? 1 : 0;
       int delta = target - mu[i];
       mu[i] = delta;

       for(int j = i + i ; j < maxn; j+=i)
           mu[j] +=delta;
  }
}

int main()
{
   getMu();

   int T;
   scanf("%d",&T);
   for(int z = 1; z <= T; z++) {
       int a,b,c,d,k;
       scanf("%d%d%d%d%d",&a,&b,&c,&d,&k);
       if(k==0) {
           puts("0");
           continue;
      }
       b/=k;
       d/=k;
       if(b>d) swap(b,d);  //b小
       long long ans1 = 0;
       for(int i = 1; i <= b; i++)
           ans1 += (long long)mu[i]*(b/i)*(d/i);

       long long ans2 = 0;
       for(int i = 1; i <= b; i++)            ans2 += (long long)mu[i]*(b/i)*(b/i);        ans1 -= ans2/2;        printf("%I64d\n",ans1);   }​​    return 0;}

例题三:

题意:给定一个正方体的区间,从坐标(0,0,0)处可以看到多少个整点?

分析:(1,1,1) 能看到,但是(2,2,2)就三点共线挡住了,同理(2,3,4)能看到,但是(4,6,8)就看不到了,可以看出就是 的点,被除以gcd的点挡住了。也就是求 (x,y,z)互质的点对,就是上一题加一维。

值得注意的是区间是[1,n],整个坐标系可以x = 0等,x等于0,相当于一个平面,减一围。

还有3个坐标轴上的点。

#include <bits/stdc++.h>

using namespace std;

const int maxn = 1<<20;
int mu[maxn];


//求莫比乌斯函数
void getMu() {
   for(int i = 1; i < maxn; i++) {
       int target = i == 1 ? 1 : 0;
       int delta = target - mu[i];
       mu[i] = delta;

       for(int j = i + i ; j < maxn; j+=i)
           mu[j] +=delta;
  }
}

typedef long long ll;

int main()
{
   getMu();

   int t;
   scanf("%d",&t);
   while(t--) {
       int n;
       scanf("%d",&n);

       ll ans = 3;
       for(int i = 1; i <= n; i++)
           ans+= (ll)mu[i]*(n/i)*(n/i)*(n/i+3);
       printf("%lld\n",ans);


  }
   return 0;
}

到此,你就已经入门莫比乌斯了~~~

TreeDream

ACM-ICPC (10/11)的更多相关文章

  1. hduoj 4715 Difference Between Primes 2013 ACM/ICPC Asia Regional Online —— Warmup

    http://acm.hdu.edu.cn/showproblem.php?pid=4715 Difference Between Primes Time Limit: 2000/1000 MS (J ...

  2. 2016 ACM/ICPC Asia Regional Qingdao Online 1001/HDU5878 打表二分

    I Count Two Three Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others ...

  3. 2016 ACM/ICPC Asia Regional Shenyang Online 1009/HDU 5900 区间dp

    QSC and Master Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) ...

  4. 2016 ACM/ICPC Asia Regional Dalian Online 1006 /HDU 5873

    Football Games Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)To ...

  5. 2015 ACM / ICPC 亚洲区域赛总结(长春站&北京站)

    队名:Unlimited Code Works(无尽编码)  队员:Wu.Wang.Zhou 先说一下队伍:Wu是大三学长:Wang高中noip省一:我最渣,去年来大学开始学的a+b,参加今年区域赛之 ...

  6. 2016 ACM/ICPC Asia Regional Qingdao Online(2016ACM青岛网络赛部分题解)

    2016 ACM/ICPC Asia Regional Qingdao Online(部分题解) 5878---I Count Two Three http://acm.hdu.edu.cn/show ...

  7. 2017 ACM/ICPC Asia Regional Qingdao Online

    Apple Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Total Submi ...

  8. ACM/ICPC 之 BFS(离线)+康拓展开(TSH OJ-玩具(Toy))

    祝大家新年快乐,相信在新的一年里一定有我们自己的梦! 这是一个简化的魔板问题,只需输出步骤即可. 玩具(Toy) 描述 ZC神最擅长逻辑推理,一日,他给大家讲述起自己儿时的数字玩具. 该玩具酷似魔方, ...

  9. ACM ICPC 2015 Moscow Subregional Russia, Moscow, Dolgoprudny, October, 18, 2015 D. Delay Time

    Problem D. Delay Time Input file: standard input Output file: standard output Time limit: 1 second M ...

  10. hduoj 4710 Balls Rearrangement 2013 ACM/ICPC Asia Regional Online —— Warmup

    http://acm.hdu.edu.cn/showproblem.php?pid=4710 Balls Rearrangement Time Limit: 6000/3000 MS (Java/Ot ...

随机推荐

  1. java se系列(四) 函数、数组、排序算法、二分法、二维数组

    1 函数 1.1  数的概述 发现不断进行加法运算,为了提高代码的复用性,就把该功能独立封装成一段独立的小程序,当下次需要执行加法运算的时候,就可以直接调用这个段小程序即可,那么这种封装形形式的具体表 ...

  2. (转)linux shell单引号、双引号及无引号区别

    原文:http://blog.csdn.net/woshizhangliang999/article/details/50132265 3.描述linux shell中单引号.双引号及不加引号的简单区 ...

  3. 关于TypeScript中null,undefined的使用

    TypeScript本质是javascript,因此基本上js所有的功能在ts上完全可以照搬照抄过来使用.根据ts的文档,有些我觉得值得商榷的——比如null,undefined就是例子. 文档上说一 ...

  4. 下载Dubbo源码后的编译安装启动

    1:安装jdk,maven       配制环境变量: 2:安装zookeeper      配制zookeeper环境变量 3:把dubbo源码编译成war包 启动cmd黑窗口  ,进入  源码文件 ...

  5. mobile开发技巧(转)

    1.隐藏地址栏 很多文档介绍通过调用 window.scrollTo(0, 1); 就可以隐藏地址栏,但是通过实践发现隐藏地址栏还是真够坑爹的啊,只调用这一句话一般不会起作用,我们需要 functio ...

  6. Hashtable和HashMap的区别,Properties类的简单使用

    一.Java Properties类 Java中有个比较重要的类Properties(Java.util.Properties),主要用于读取Java的配置文件,各种语言都有自己所支持的配置文件,配置 ...

  7. IE67不兼容display:inline-block,CSS hack解决

    追加以下代码:*display:inline.*zoom:1 ;} 块元素变为内联块, IE67不兼容:内联元素变为内联块,所有浏览器都支持 发现问题:当然,变为内联块后,有一个特性就是如果元素换行, ...

  8. 06.do-while循环的练习

    练习1: namespace _09.do_while循环练习01 { class Program { static void Main(string[] args) { //计算1到100之间的整数 ...

  9. Gitflow 工作流程

    目存在两个长期分支: 主分支master 开发分支develop 前者用于存放对外发布的版本,任何时候在这个分支拿到的,都是稳定的分布版: 后者用于日常开发,存放最新的开发版. 其次,开发新功能或者修 ...

  10. Html-知识总结

    1.Html概述 1.1什么是Html Html:超文本标记语言(hyperText Markup Language) “超文本”加上指页面内可以包含图片,链接等非文字内容. “标记”就是使用标签的方 ...