又是一道经典题.

1.学习了下O(n) 的做法。

//
// main.cpp
// bzoj2154
//
// Created by New_Life on 16/7/7.
// Copyright © 2016年 chenhuan001. All rights reserved.
// #include <iostream>
#include <string.h>
#include <stdio.h>
using namespace std; #define N 10001000
#define MOD 20101009 //--莫比乌斯反演函数--//
//说明:利用线性素数筛选顺便求了个mu
//注释部分为求从区间[1,b]和区间[1,d]中取两个数,互质对数O(n^0.5)
//复杂度:O(n)
int mu[N];
long long sum[N];
int prime[N];
bool mark[N]; void mobus()
{
int pcnt=;
memset(mark,,sizeof(mark));
mu[] = ;
for(int i=;i<N;i++)
{
if(mark[i] == )
{
prime[pcnt++] = i;
mu[i] = -;
}
for(int j=;j<pcnt && i*prime[j]<N;j++)
{
int tmp = i*prime[j];
mark[tmp] = ;
if( i%prime[j] == )
{
mu[tmp] = ;
break;
} mu[tmp] = mu[i]*-;
}
}
for(int i=;i<N;i++)
{
sum[i] += sum[i-]+(long long)mu[i]*i*i;
sum[i] %= MOD;
}
} long long gaobili(long long b,long long d)
{
if(b<=||d<=) return ;
long long m = min(b,d);
long long ans = ;
while(m>=)
{
long long tb = b/( b/m + )+;
long long td = d/( d/m + )+;
//前进的最大位置
long long tm = max(tb,td);
ans += (sum[m]-sum[tm-])*(((b/m+)*(b/m)/)%MOD)%MOD*(((d/m+)*(d/m)/)%MOD)%MOD ;
ans %= MOD;
m = tm-;
}
return ans;
}
//等差数列求和模板,[a1,a1+d,...,an]
long long allsum(long long a1,long long an,long long n)
{
if(n%==)
return (a1+an)*(n/);
else return ((a1+an)/)*n;
} int main(int argc, const char * argv[]) {
mobus();
int b,d;
while(scanf("%d%d",&b,&d)!=EOF)
{
int m = min(b,d);
long long ans = ;
while(m>=)
{
int tb = b/( b/m + )+;
int td = d/( d/m + )+;
//前进的最大位置
int tm = max(tb,td);
ans += allsum(tm,m,m-tm+)%MOD*gaobili(b/m, d/m)%MOD;
ans %= MOD;
m = tm-;
}
cout<<(ans+MOD)%MOD<<endl;
}
return ;
}
/*
4 5 */

2.O(n)预处理,每次查询n^0.5

因为bzoj2693题目找不到了,所以直接用了这题来测试。

这题首先是一个经典的公式变形。 交换连加时变量的位置。

而根据第二个重要的性质,乘性函数的乘除之后还是乘性函数。(加减并不是)

所以后面的连加部分也是乘性函数,这时只需要的单独看只含一个因子的时候,因为里面含有u(i),所以对于D=x^k(x是素因子)只有当i = 1 或 x 时不为0,所以

后面的为x^k(1-x)。这时可以在线性筛选时顺便求出来。

**************************************************************
Problem:
User: chenhuan001
Language: C++
Result: Accepted
Time: ms
Memory: kb
****************************************************************/ #include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <algorithm>
#include <iostream>
using namespace std;
//--莫比乌斯反演函数--//
//说明:利用线性素数筛选顺便求了个mu
//注释部分为求从区间[1,b]和区间[1,d]中取两个数,互质对数O(n^0.5)
//复杂度:O(n)
#define N 10000010
bool mark[N];
int prime[N/]; long long sum[N]; #define MOD 20101009 void mobus()
{
int pcnt=; sum[] = ;
for(int i=;i<N;i++)
{
if(mark[i] == )
{
prime[pcnt++] = i; sum[i] = (long long)i*(-i)%MOD;
}
for(int j=;j<pcnt && i*prime[j]<N;j++)
{
int tmp = i*prime[j];
mark[tmp] = ;
if( i%prime[j] == )
{
sum[tmp] = sum[i]*prime[j];
sum[tmp] %= MOD; break;
}
else
{
sum[tmp] = sum[i]*(sum[prime[j]])%MOD;
} }
}
for(int i=;i<N;i++)
sum[i] = (sum[i]+sum[i-])%MOD;
} long long gaobili(int b,int d)
{
if(b<=||d<=) return ;
long long m = min(b,d);
long long ans = ;
while(m>=)
{
long long tb = b/( b/m + )+;
long long td = d/( d/m + )+;
//前进的最大位置
long long tm = max(tb,td);
ans += (sum[m]-sum[tm-])*(((b/m+)*(b/m)/)%MOD)%MOD*(((d/m+)*(d/m)/)%MOD)%MOD;
ans %= MOD;
m = tm-;
}
return (ans+MOD)%MOD;
} int main()
{
mobus();
int b,d;
while(scanf("%d%d",&b,&d)!=EOF)
{
printf("%d\n",(int)gaobili(b,d));
}
return ;
}

至此mobus大概都刷了一遍,原以为很复杂的东西,其实也不是很难。以后面对的题目可能有更多的公式变形,或许难在找出莫比乌斯模型。但基本的也就是这些方法了。

治好了多年的公式恐惧症。。

bzoj2154(莫比乌斯反演)的更多相关文章

  1. 【BZOJ2154】Crash的数字表格(莫比乌斯反演)

    [BZOJ2154]Crash的数字表格(莫比乌斯反演) 题面 BZOJ 简化题意: 给定\(n,m\) 求\[\sum_{i=1}^n\sum_{j=1}^mlcm(i,j)\] 题解 以下的一切都 ...

  2. Bzoj2154 Crash的数字表格 乘法逆元+莫比乌斯反演(TLE)

    题意:求sigma{lcm(i,j)},1<=i<=n,1<=j<=m 不妨令n<=m 首先把lcm(i,j)转成i*j/gcd(i,j) 正解不会...总之最后化出来的 ...

  3. 【莫比乌斯反演】BZOJ2154 Crash的数字表格

    Description 求sigma lcm(x,y),x<=n,y<=m.n,m<=1e7. Solution lcm没有什么直接做的好方法,用lcm=x*y/gcd转成gcd来做 ...

  4. 【bzoj2154】Crash的数字表格 莫比乌斯反演

    题目描述 今天的数学课上,Crash小朋友学习了最小公倍数(Least Common Multiple).对于两个正整数a和b,LCM(a, b)表示能同时被a和b整除的最小正整数.例如,LCM(6, ...

  5. [复习]莫比乌斯反演,杜教筛,min_25筛

    [复习]莫比乌斯反演,杜教筛,min_25筛 莫比乌斯反演 做题的时候的常用形式: \[\begin{aligned}g(n)&=\sum_{n|d}f(d)\\f(n)&=\sum_ ...

  6. 【bzoj2693】jzptab 莫比乌斯反演+线性筛

    题目描述 输入 一个正整数T表示数据组数 接下来T行 每行两个正整数 表示N.M 输出 T行 每行一个整数 表示第i组数据的结果 样例输入 1 4 5 样例输出 122 题解 莫比乌斯反演+线性筛 由 ...

  7. 【BZOJ2693】jzptab [莫比乌斯反演]

    jzptab Time Limit: 10 Sec  Memory Limit: 512 MB[Submit][Status][Discuss] Description   求 Input 第一行一个 ...

  8. 莫比乌斯反演/线性筛/积性函数/杜教筛/min25筛 学习笔记

    最近重新系统地学了下这几个知识点,以前没发现他们的联系,这次总结一下. 莫比乌斯反演入门:https://blog.csdn.net/litble/article/details/72804050 线 ...

  9. hdu1695 GCD(莫比乌斯反演)

    题意:求(1,b)区间和(1,d)区间里面gcd(x, y) = k的数的对数(1<=x<=b , 1<= y <= d). 知识点: 莫比乌斯反演/*12*/ 线性筛求莫比乌 ...

随机推荐

  1. 链接注入(便于跨站请求伪造)(AppScan扫描结果)

    最近工作要求解决下web的项目的漏洞问题,扫描漏洞是用的AppScan工具,其中此篇文章是关于链接注入问题的.下面就把这块东西分享出来. 原创文章,转载请注明 -------------------- ...

  2. poj1703 Lost Cows

    给定集合{1,2,...,n}的一个置换,指定每个位置上在其左方且比其小的数的个数,求该置换. 这题我目前还只会O(n^2)的做法. 以后再用更高效的算法解决. http://poj.org/prob ...

  3. java截取字符串中的数字

    java从字符串中提取数字 随便给你一个含有数字的字符串,比如: String s="eert343dfg56756dtry66fggg89dfgf"; 那我们如何把其中的数字提取 ...

  4. Children of the Candy Corn 分类: POJ 2015-07-14 08:19 7人阅读 评论(0) 收藏

    Children of the Candy Corn Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 10933   Acce ...

  5. ISO C90 forbids mixed declarations and code 警告

    编译的时候经常会遇到   ISO C90 forbids mixed declarations and code 警告百度了一下,知道是如下原因 : 变量定义之前任何一条非变量定义的语句(注意:语句是 ...

  6. hdu 4002 Find the maximum

    Find the maximum Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65768/65768 K (Java/Others) ...

  7. poj 1430 Binary Stirling Numbers

    Binary Stirling Numbers Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 1761   Accepted ...

  8. js的Prototype属性 解释及常用方法

    函数:原型 每一个构造函数都有一个属性叫做原型(prototype,下面都不再翻译,使用其原文).这个属性非常有用:为一个特定类声明通用的变量或者函数. prototype的定义 你不需要显式地声明一 ...

  9. django下的ckeditor 5.0 文本编辑器上传功能。

    完整的后台界面怎么可以没有文本编辑器,但是django的admin界面很疑惑,没有自带文本编辑器,好在网上有不少成型的库可以用 我用的是ckeditor编辑器,安装和配置我引用别人的博客 这篇博客配置 ...

  10. 解决Duilib创建的win32窗口拖到屏幕上边缘自动最大化

    转载:http://bbs.csdn.net/topics/390842294 使用Duilib创建窗口的时候,假如有这样一个需求: 1.窗口大小规定 2.不可拖拽改变窗口大小 3.双击标题栏禁止最大 ...