【BZOJ3529】【SDOI2014】数表 (莫比乌斯反演+树状数组)
Description
有一张$n\times m$的数表,其第$i$行第$j$列 $(1≤i≤n,1≤j≤m)$ 的数值为能同时整除$i$和$j$的所有自然数之和。
现在给定$a$,计算数表中不大于$a$的数之和。
Input
输入包含多组数据。
输入的第一行一个整数$Q$表示测试点内的数据组数,接下来Q行,每行三个整数$n,m,a(a≤109)$描述一组数据。
Output
题解:
我数学太水了!!又是一道推公式的题:
\begin{aligned}
ans&=\sum^n_{i=1}\sum^m_{j=1}\sum_{d\mid gdc(i,j)}d\\
&=\sum_d^n\sum^{\lfloor\frac{n}{d}\rfloor}_{i=1}\sum^{\lfloor\frac{m}{d}\rfloor}_{j=1}f(d)[gcd(i,j)=1] &(f(d)=\sum_{k\mid d}k)\\
&=\sum_d^n f(d)\sum^{\lfloor\frac{n}{d}\rfloor}_{i=1}\sum^{\lfloor\frac{m}{d}\rfloor}_{j=1}\sum_{k\mid gcd(i,j)}\mu(k)\\
&=\sum_k^n\sum_d^n f(d)\mu(k)\lfloor\frac{n}{kd}\rfloor\lfloor\frac{m}{kd}\rfloor\\
&设 T=kd \\
ans&=\sum_T^n\sum_{d\mid T}f(d)\mu(\frac{T}{d})\lfloor\frac{n}{T}\rfloor\lfloor\frac{m}{T}\rfloor\\
\end{aligned}
前面同样是数论分块,后面依旧是线性筛。
考虑f怎么求
有个约数和定理
若$n=\sum_{i=1}^k p_i^{a_i}$,$p_i$为$n$的质因数,那么$n$的约数和 $f(n)$满足$f(n)=\prod_{i=1}^k\sum_{j=0}^{a_i}p_i^j$
$f$的话首先是个积性函数,我们在筛$\mu$的时候想顺便把这个也筛出来
考虑$f(d)$的值,如果说d是质数的话答案显然是$d+1$,下面讨论$d$为合数的情况
设$d=i*p$,其中$p$为质数
$p\nmid i$,那么$p$和$i$互质,所以$f(d)=f(p)*f(i)$
$p∣i$,设$i=t*p^x$ ,那么根据约数和定理,我们可以得
$$f(i*p) = f(t)f(p^{x+1}) = f(t)\sum\limits_{i=0}^{x+1}p^i$$
然后我们把p0(也就是1)拿出来,得到
$$f(i * p) = f(t) + f(t)*\sum\limits_{i=1}^{x+1}p^i = f(t) + f(t)*f(p^x)*p$$
然后$i = t * p^x$,所以$f(t) * f(p^x) = f(i)$
所以最后就是$f(d) = f(t) + f(i) * p$
然后就可以筛出$f(d)$啦
剩下的东西
现在加上a的限制,其实就是离线处理
我们先将所有的询问按照a的大小排序,然后从小到大处理
因为分块的时候我们要用到的是g(x)的前缀和,所以用一个树状数组来处理
将f(x)排个序,枚举的时候只枚举到f(x)<a,然后枚举另一个约数求出g,丢到树状数组里面去
求答案的时候直接查询就好了
CODE:
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std; #define lowbit(x) (x&-x)
int T,cnt=,maxn,ans[],tmp[];
int f[],pri[],c[],mu[];
bool vis[];
struct Que{
int n,m,a,id;
bool operator<(const Que &b)const{
return a<b.a;
}
}q[]; bool comp(int a,int b){return f[a]<f[b];} void init(){
mu[]=f[]=;
for(int i=;i<=maxn;i++){
if(!vis[i]){
f[i]=i+,mu[i]=-;
pri[++cnt]=i;
}
for(int j=;j<=cnt&&i*pri[j]<=maxn;j++){
vis[i*pri[j]]=true;
if(i%pri[j]==){
mu[i*pri[j]]=;
int t=i;
while(t%pri[j]==)t/=pri[j];
f[i*pri[j]]=f[t]+pri[j]*f[i];
break;
}else{
f[i*pri[j]]=f[i]*f[pri[j]];
mu[i*pri[j]]=-mu[i];
}
}
}
} void add(int x,int y){
while(x<=maxn){
c[x]+=y;
x+=lowbit(x);
}
} int sum(int x){
int ans=;
while(x>=){
ans+=c[x];
x-=lowbit(x);
}
return ans;
} int main(){
scanf("%d",&T);
for(int i=;i<=T;i++){
scanf("%d%d%d",&q[i].n,&q[i].m,&q[i].a);
q[i].id=i;
if(q[i].n>q[i].m)swap(q[i].n,q[i].m);
maxn=max(maxn,q[i].n);
}
init();
sort(q+,q+T+);
for(int i=;i<=maxn;i++)tmp[i]=i;
sort(tmp+,tmp+maxn+,comp);
for(int i=,now=;i<=T;i++){
int n=q[i].n,m=q[i].m,a=q[i].a;
while(now<=maxn&&f[tmp[now]]<=a){
for(int k=;k*tmp[now]<=maxn;k++)
add(k*tmp[now],f[tmp[now]]*mu[k]);
now++;
}
for(int j=,pos;j<=n;j=pos+){
pos=min(n/(n/j),m/(m/j));
ans[q[i].id]+=(n/j)*(m/j)*(sum(pos)-sum(j-));
}
}
for(int i=;i<=T;i++)
printf("%d\n",ans[i]&0x7fffffff);
}
【BZOJ3529】【SDOI2014】数表 (莫比乌斯反演+树状数组)的更多相关文章
- BZOJ3529: [Sdoi2014]数表(莫比乌斯反演 树状数组)
题意 题目链接 Sol 首先不考虑\(a\)的限制 我们要求的是 \[\sum_{i = 1}^n \sum_{j = 1}^m \sigma(gcd(i, j))\] 用常规的套路可以化到这个形式 ...
- 【BZOJ3529】[Sdoi2014]数表 莫比乌斯反演+树状数组
[BZOJ3529][Sdoi2014]数表 Description 有一张N×m的数表,其第i行第j列(1 < =i < =礼,1 < =j < =m)的数值为能同时整除i和 ...
- BZOJ 3259 [Sdoi2014]数表 (莫比乌斯反演 + 树状数组)
3529: [Sdoi2014]数表 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 2321 Solved: 1187[Submit][Status ...
- BZOJ 3529: [Sdoi2014]数表 [莫比乌斯反演 树状数组]
3529: [Sdoi2014]数表 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 1399 Solved: 694[Submit][Status] ...
- BZOJ 3529 [Sdoi2014]数表 (莫比乌斯反演+树状数组+离线)
题目大意:有一张$n*m$的数表,第$i$行第$j$列的数是同时能整除$i,j$的所有数之和,求数表内所有不大于A的数之和 先是看错题了...接着看对题了发现不会做了...刚了大半个下午无果 看了Po ...
- BZOJ 3529 [Sdoi2014]数表 ——莫比乌斯反演 树状数组
$ans=\sum_{i=1}^n\sum_{j=1}^n\sigma(gcd(i,j))$ 枚举gcd为d的所有数得到 $ans=\sum_{d<=n}\sigma(d)*g(d)$ $g(d ...
- luogu3312 [SDOI2014]数表 (莫比乌斯反演+树状数组)
link \(\sum_{i=1}^n\sum_{j=1}^m[s(\gcd(i,j))\le a]s(\gcd(i,j))\) \(=\sum_{p=1}^ns(p)[s(p)\le a]\sum_ ...
- 【BZOJ3529】【莫比乌斯反演 + 树状数组】[Sdoi2014]数表
Description 有一张N×m的数表,其第i行第j列(1 < =i < =礼,1 < =j < =m)的数值为 能同时整除i和j的所有自然数之和.给定a,计算数表中不大于 ...
- bzoj 3529 数表 莫比乌斯反演+树状数组
题目大意: 有一张N×m的数表,其第i行第j列(1 < =i < =礼,1 < =j < =m)的数值为能同时整除i和j的所有自然数之和.给定a,计算数表中不大于a的数之和. ...
随机推荐
- 《队长说得队》【Alpha】Scrum meeting 4
项目 内容 这个作业属于哪个课程 >>2016级计算机科学与工程学院软件工程(西北师范大学) 这个作业的要求在哪里 >>实验十二 团队作业8:软件测试与ALPHA冲刺 团队名称 ...
- Service Unavailable HTTP Error 503. The service is unavailable.
原因: public void SetCurrentType(string[] projTypes) { _ProjTypes = _ProjTypes; } 确保没有无限递归或无限循环
- graphviz 绘制架构图
架构图: 1.依赖调用关系.(类似文献引用关系, graphviz 自动将每一次调用升一次层级) 2.依赖调用可能是上下层级调用,也可能是同层级引用. 需人工去梳理出这些关系 3. 引用多的用颜色标识 ...
- redis基础知识学习
数据结构:1.String 添加: set key value get key getset key value (先get再set) incr key (key对应value原子性递增1) decr ...
- Java开发小游戏 用键盘控制精灵在游戏中上下左右跑动 窗体小游戏可打包下载,解压后双击start运行
package com.swift; import java.awt.Point; import java.awt.event.KeyEvent; import com.rupeng.game.Gam ...
- 18.Yii2.0框架模型修改记录 和 修改点击量
目录 修改数据 修改点击量 修改数据 上面要 use app\models\Article; //修改 //http://yii.com/?r=home/Edit public function ac ...
- 12.Yii2.0框架视图模版继承与模版相互调用
目录 模板渲染的两种方式 加载视图 index.php 和 about.php 页面 建立控制器HomeController php 新建模板 home\index.php 新建模板home\abou ...
- Golang map并发 读写锁
golang并发 一:只有写操作 var ( count int l = sync.Mutex{} m = make(map[int]int) ) //全局变量并发写 导致计数错误 func vari ...
- and和or运算
and和or的运算,从前向后按顺序计算,当True结果遇到or就停止,返回True:当False结果遇到and就停止,返回False:False遇到or,继续走:True遇到and,继续走. > ...
- Virtual Friends HDU - 3172 (并查集+秩+map)
These days, you can do all sorts of things online. For example, you can use various websites to make ...