51nod 1584 加权约数和 约数和函数小trick 莫比乌斯反演
LINK:加权约数和
我曾经一度认为莫比乌斯反演都是板子题.
做过这道题我认输了 不是什么东西都是板子.
一个trick 设\(s(x)\)为x的约数和函数.
有 \(s(i\cdot j)=\sum_{x|i}\sum_{y|j}[(x,y)==1]x\cdot \frac{j}{y}\)
证明的话可以自己意会 赶时间.
然后 这道题唯一特别的是转换完后 直接莽推根号做法是行不通的 同时也过不去.
不如先考虑求 \(f_i=\sum_{j=1}^i s(i\cdot j)\)
然后带入上面的那个trick 莫比乌斯反演一波 发现什么都得不到.
此时 配合上面trick的转换是 \(f_i=\sum_{j=1}^i\sum_{x|j,x|i}\mu(x)\sum_{u|i,x|u}\sum_{v|j,x|v}u\frac{j}{v}\)
绝妙或者是套路的转换为 \(f_i=\sum_{j=1}^i\sum_{x|j,x|i}\mu(x)s(x\cdot s(\frac{i}{x}))s(\frac{j}{x})\)
下面颠倒求和即可.
然后就可以做了 复杂度 \(nlnn+T\)
code
//#include<bits/stdc++.h>
#include<iostream>
#include<cstdio>
#include<ctime>
#include<cctype>
#include<queue>
#include<deque>
#include<stack>
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cstring>
#include<string>
#include<ctime>
#include<cmath>
#include<cctype>
#include<cstdlib>
#include<queue>
#include<deque>
#include<stack>
#include<vector>
#include<algorithm>
#include<utility>
#include<bitset>
#include<set>
#include<map>
#define ll long long
#define db double
#define INF 1000000000000000000ll
#define inf 100000000000000000ll
#define ldb long double
#define pb push_back
#define put_(x) printf("%d ",x);
#define get(x) x=read()
#define gt(x) scanf("%d",&x)
#define gi(x) scanf("%lf",&x)
#define put(x) printf("%d\n",x)
#define putl(x) printf("%lld\n",x)
#define rep(p,n,i) for(RE int i=p;i<=n;++i)
#define go(x) for(int i=lin[x],tn=ver[i];i;tn=ver[i=nex[i]])
#define fep(n,p,i) for(RE int i=n;i>=p;--i)
#define vep(p,n,i) for(RE int i=p;i<n;++i)
#define pii pair<int,int>
#define mk make_pair
#define RE register
#define P 1000000007ll
#define gf(x) scanf("%lf",&x)
#define pf(x) ((x)*(x))
#define uint unsigned long long
#define ui unsigned
#define EPS 1e-10
#define sq sqrt
#define S second
#define F first
#define mod 1000000007
#define max(x,y) ((x)<(y)?y:x)
using namespace std;
char *fs,*ft,buf[1<<15];
inline char gc()
{
return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:*fs++;
}
inline int read()
{
RE int x=0,f=1;RE char ch=gc();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=gc();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=gc();}
return x*f;
}
const int MAXN=1000010;
int n,T,top;
int v[MAXN],p[MAXN],d[MAXN],sum[MAXN],D[MAXN],w[MAXN],f[MAXN],in[MAXN],mu[MAXN];
inline int add(int x,int y){return x+y>=mod?x+y-mod:x+y;}
inline int mul(int x,int y){return (ll)x*y%mod;}
inline int mus(int x,int y){return x-y<0?x-y+mod:x-y;}
inline int ksm(int b,int p)
{
int cnt=1;
while(p)
{
if(p&1)cnt=mul(cnt,b);
b=mul(b,b);p=p>>1;
}
return cnt;
}
inline void prepare()
{
sum[1]=mu[1]=in[1]=d[1]=D[1]=1;
rep(2,n,i)
{
in[i]=mul(in[mod%i],(mod-mod/i));
if(!v[i])
{
v[i]=p[++top]=i;mu[i]=-1;
w[i]=p[top];d[i]=i+1;
D[i]=add(1+i,(ll)i*i%mod);
}
sum[i]=add(d[i],sum[i-1]);
rep(1,top,j)
{
if(p[j]>n/i)break;
int ww=p[j]*i;
v[ww]=p[j];
if(v[i]==p[j])
{
w[ww]=w[i]*p[j];
if(w[ww]==ww)
{
d[ww]=add(d[i],ww);
D[ww]=add(D[i],add((ll)ww*ww%mod,(ll)i*i%mod*p[j]%mod));
}
else
{
d[ww]=mul(d[i/w[i]],d[w[ww]]);
D[ww]=mul(D[i/w[i]],D[w[ww]]);
}
break;
}
w[ww]=p[j];d[ww]=mul(d[i],d[p[j]]);
D[ww]=mul(D[i],D[p[j]]);
mu[ww]=-mu[i];
}
}
/*rep(1,1000,i)
{
if(D[i]!=d[i*i])
{
cout<<"ww"<<endl;
cout<<i<<endl;
return;
}
}*/
rep(1,n,i)
{
if(mu[i])
{
for(int j=i;j<=n;j+=i)
f[j]=(f[j]+mu[i]*(ll)i*d[j/i]%mod*sum[j/i])%mod;
}
f[i]=((mul(f[i],2*i)-mul(i,D[i]))%mod+mod)%mod;
f[i]=add(f[i],f[i-1]);
}
}
signed main()
{
//freopen("1.in","r",stdin);
n=1000000;prepare();
get(T);
rep(1,T,W)
{
printf("Case #%d: ",W);
put(f[read()]);
}
return 0;
}
51nod 1584 加权约数和 约数和函数小trick 莫比乌斯反演的更多相关文章
- 51NOD 1584 加权约数和 [莫比乌斯反演 转化 Trick]
1584 加权约数和 题意:求\(\sum_{i=1}^{N} \sum_{j=1}^{N} {\max(i,j)\cdot \sigma(i\cdot j)}\) 多组数据\(n \le 10^6, ...
- [51Nod 1584] 加权约数和
Description 在整理以前的试题时,他发现了这样一道题目:"求 \(\sum\sigma(i)\),其中 \(1≤i≤N\),\(σ(i)\) 表示 \(i\) 的约数之和.&quo ...
- 51nod 1584加权约数和
学到了好多东西啊这题... https://blog.csdn.net/sdfzyhx/article/details/72968468 #include<bits/stdc++.h> u ...
- 51Nod 欢乐手速场1 C 开心的小Q[莫比乌斯函数]
开心的小Q tangjz (命题人) quailty (测试) 基准时间限制:1 秒 空间限制:131072 KB 分值: 80 如果一个数字存在一个约数是完全平方数,那么小Q就认为这个数是有趣的 ...
- 【BZOJ3994】约数个数和(莫比乌斯反演)
[BZOJ3994]约数个数和(莫比乌斯反演) 题面 求\[\sum_{i=1}^n\sum_{j=1}^md(ij)\] 多组数据\((<=50000组)\) \(n,m<=50000\ ...
- 【BZOJ3994】[SDOI2015] 约数个数和(莫比乌斯反演)
点此看题面 大致题意: 设\(d(x)\)为\(x\)的约数个数,求\(\sum_{i=1}^N\sum_{j=1}^Md(i·j)\). 莫比乌斯反演 这是一道莫比乌斯反演题. 一个重要的性质 首先 ...
- [SDOI2015][bzoj 3994][Luogu P3327] 约数个数和 (莫比乌斯反演)
题目描述 设d(x)d(x)d(x)为xxx的约数个数,给定NNN.MMM,求 ∑i=1N∑j=1Md(ij)\sum^{N}_{i=1}\sum^{M}_{j=1} d(ij)i=1∑Nj=1∑M ...
- BZOJ_3994_[SDOI2015]约数个数和_莫比乌斯反演
BZOJ_3994_[SDOI2015]约数个数和_莫比乌斯反演 Description 设d(x)为x的约数个数,给定N.M,求 Input 输入文件包含多组测试数据. 第一行,一个整数T,表 ...
- 洛谷P3327 [SDOI2015]约数个数和 【莫比乌斯反演】
题目 设d(x)为x的约数个数,给定N.M,求\(\sum_{i = 1}^{N} \sum_{j = 1}^{M} d(ij)\) 输入格式 输入文件包含多组测试数据.第一行,一个整数T,表示测试数 ...
随机推荐
- css中line-height的理解_介绍line-height实际应用
一.line-height的定义 css中line-height行高是指文本行基线之间的距离,不同字体,基线位置不同.line-height只影响行内元素和其他行内内容,而不会直接影响块级元素,如果块 ...
- H5禁止微信内置浏览器调整字体大小
微信webview内置了调整字体大小的功能,用户可以根据实际情况进行调节.但是这也会导致字体大小改变以后,出现页面布局错乱的情况. 1.iOS的解决方案是覆盖掉微信的样式: body { /* IOS ...
- List集合-03.Vector
3.Vector 3.1 UML图 3.2 Vector的特点 Object的数组存储元素 默认初始大小为10 public Vector() { this(10); } 线程安全,可以看到所有的数据 ...
- Linux终端音乐播放器cmus攻略: 操作歌单
目录 1. 安装 2. 操作说明 2.1. *PlayList歌单 2.2. 其他 3. 视图切换 4. 使响应Media/play按键 4.1. 编译安装 cmus是一款开源的终端音乐播放器.它小巧 ...
- [JAVA]字符串常量池String pool
字符串常量池(String Pool)保存着所有字符串字面量(literal strings),这些字面量在编译时期就确定.不仅如此,还可以使用 String 的 intern() 方法在运行过程中将 ...
- Java面向对象详解-上
一.类及对象 1. 类的组成成分 属性(成员变量,Field) 方法(成员方法,函数,Method) 2. 属性 成员变量 vs 局部变量 相同点: 遵循变量声明的格式: 数据类型 变量名 = 初始化 ...
- Scala 基础(十四):Scala 模式匹配(二)
1 匹配数组 1)Array(0) 匹配只有一个元素且为0的数组. 2)Array(x,y) 匹配数组有两个元素,并将两个元素赋值为x和y.当然可以依次类推Array(x,y,z) 匹配数组有3个元素 ...
- scala 数据结构(六):映射 Map
1 映射 Map-基本介绍 Scala中的Map介绍 1) Scala中的Map 和Java类似,也是一个散列表,它存储的内容也是键值对(key-value)映射,Scala中不可变的Map是有序的, ...
- Ethical Hacking - GAINING ACCESS(22)
CLIENT SIDE ATTACKS - BeEf Framework Browser Exploitation Framework allowing us to launch a number o ...
- Spring声明式事务快速上手
1.什么是事务 首先我们要知道什么是事务.知其然,才能知其所以然. 事务(Transaction)是一个业务,是一个不可分割的逻辑工作单元,基于事务可以更好的保证业务的正确性. 这么说可能有点难以理解 ...