传送门

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

对每组数据,输出一行一个整数,表示答案模$2^{31}$的值。 

题解:

我数学太水了!!又是一道推公式的题:

\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】数表 (莫比乌斯反演+树状数组)的更多相关文章

  1. BZOJ3529: [Sdoi2014]数表(莫比乌斯反演 树状数组)

    题意 题目链接 Sol 首先不考虑\(a\)的限制 我们要求的是 \[\sum_{i = 1}^n \sum_{j = 1}^m \sigma(gcd(i, j))\] 用常规的套路可以化到这个形式 ...

  2. 【BZOJ3529】[Sdoi2014]数表 莫比乌斯反演+树状数组

    [BZOJ3529][Sdoi2014]数表 Description 有一张N×m的数表,其第i行第j列(1 < =i < =礼,1 < =j < =m)的数值为能同时整除i和 ...

  3. BZOJ 3259 [Sdoi2014]数表 (莫比乌斯反演 + 树状数组)

    3529: [Sdoi2014]数表 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 2321  Solved: 1187[Submit][Status ...

  4. BZOJ 3529: [Sdoi2014]数表 [莫比乌斯反演 树状数组]

    3529: [Sdoi2014]数表 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 1399  Solved: 694[Submit][Status] ...

  5. BZOJ 3529 [Sdoi2014]数表 (莫比乌斯反演+树状数组+离线)

    题目大意:有一张$n*m$的数表,第$i$行第$j$列的数是同时能整除$i,j$的所有数之和,求数表内所有不大于A的数之和 先是看错题了...接着看对题了发现不会做了...刚了大半个下午无果 看了Po ...

  6. 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 ...

  7. 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_ ...

  8. 【BZOJ3529】【莫比乌斯反演 + 树状数组】[Sdoi2014]数表

    Description 有一张N×m的数表,其第i行第j列(1 < =i < =礼,1 < =j < =m)的数值为 能同时整除i和j的所有自然数之和.给定a,计算数表中不大于 ...

  9. bzoj 3529 数表 莫比乌斯反演+树状数组

    题目大意: 有一张N×m的数表,其第i行第j列(1 < =i < =礼,1 < =j < =m)的数值为能同时整除i和j的所有自然数之和.给定a,计算数表中不大于a的数之和. ...

随机推荐

  1. Google 出品的 Java 编码规范,强烈推荐,权威又科学!

    原文:google.github.io/styleguide/javaguide.html 译者:Hawstein 来源:hawstein.com/2014/01/20/google-java-sty ...

  2. ubuntu k8s 命令补全

    apt install bash-completion // locate bash_completion source /usr/share/bash-completion/bash_complet ...

  3. 理解AttributeUsage类

    类定义: // 摘要: // 指定另一特性类的用法. 此类不能被继承. [Serializable] [AttributeUsage(AttributeTargets.Class, Inherited ...

  4. nodejs写一个简单的Web服务器

    目录文件如 httpFile.js如下: const httpd = require("http"); const fs = require("fs"); // ...

  5. Sum All Numbers in a Range-freecodecamp算法题目

    Sum All Numbers in a Range 要求 给你一个包含两个数字的数组.返回这两个数字和它们之间所有数字的和. 最小的数字并非总在最前面. 思路 定义结果变量num 在for循环中,i ...

  6. NOIP模拟赛 水灾

    大雨应经下了几天雨,却还是没有停的样子.土豪CCY刚从外地赚完1e元回来,知道不久除了自己别墅,其他的地方都将会被洪水淹没. CCY所在的城市可以用一个N*M(N,M<=50)的地图表示,地图上 ...

  7. [51nod] 1301 集合异或和

    考虑不限制xor{Y}>xor{X} 考虑n=m的情况,每个数i∈[1,n]可以被分配到X集合或Y集合,或不分配 设f[S]表示{X} xor {Y} == S的方案数 有f[S]+=2*f[S ...

  8. Linux-Java安装

    安装 yum -y install java-1.8.0-openjdk* Tomcat安装:到官网http://tomcat.apache.org/,然后找到Tomcat9下载地址 http://m ...

  9. 【Linux命令】nohup和&差异,查看进程和终止进程!

    最近在开发dueros的技能,官方提供的PHPSDK中有多个实力,而运行实例的命令如下是 nohup php -S 0.0.0.0:8029 myindex.php & 从命令来看,肯定是在8 ...

  10. JAVA基础篇—文件与流

    处理字节流的抽象类 InputStream 是字节输入流的所有类的超类,一般我们使用它的子类,如FileInputStream等. OutputStream是字节输出流的所有类的超类,一般我们使用它的 ...