题目链接:数表

  我们一起来膜PoPoQQQ大爷的题解吧Orz

  首先我们来考虑没有\(a\)的限制该怎么做。显然交换\(n\),\(m\)答案不变,所以后面默认\(n \le m\)。

  我们定义两个函数:

\[f(x)=\sum_{d|x}d\]

\[g(x)=\sum_{i=1}^n\sum_{j=1}^m[\gcd(i,j)=x]\]

  那么显然有:\[ans=\sum_{i=1}^nf(i)g(i)\]

  \(g\)函数我们可以考虑化简一下:

\begin{aligned}
g(x)&=\sum_{i=1}^n\sum_{j=1}^m[\gcd(i,j)=x] \\
&=\sum_{i=1}^{\lfloor \frac{n}{x} \rfloor}\sum_{j=1}^{\lfloor \frac{m}{x} \rfloor}\sum_{d|i,d|j}\mu(d) \\
&=\sum_{d=1}^{\lfloor \frac{n}{x} \rfloor}\mu(d)\lfloor \frac{n}{dx} \rfloor\lfloor \frac{m}{dx} \rfloor \\
&=\sum_{x|d}\mu(\frac{d}{x})\lfloor \frac{n}{d} \rfloor\lfloor \frac{m}{d} \rfloor
\end{aligned}

  于是可以得到:

\begin{aligned}
ans=&\sum_{i=1}^nf(i)\sum_{i|d}\mu(\frac{d}{i})\lfloor \frac{n}{d} \rfloor\lfloor \frac{m}{d} \rfloor \\
=&\sum_{d=1}^n\lfloor \frac{n}{d} \rfloor\lfloor \frac{m}{d} \rfloor\sum_{i|d}f(i)\mu(\frac{d}{i})
\end{aligned}

  我们令\(h(x)=\sum_{i|x}f(i)\mu(\frac{x}{i})\),那么我们只要有\(h(x)\)的前缀和,就可以在\(O(\sqrt{n})\)的时间内求出\(ans\)了。

  然后我们来考虑\(a\)的限制。显然,只有\(f(x)\le a\)的\(f(x)\)才会对答案有影响。所以,我们把所有的询问按\(a\)从小到大排好序,并且把所有的\(f(x)\)从小到大依次加进来,使用树状数组维护前缀和,依次处理每个询问,就可以在\(O(Q\sqrt{n}\log{n}+n\log^2 n)\)的时间内解决所有询问了。

  下面贴代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
#define maxn 100010 using namespace std;
typedef long long llg; struct data{
int n,m,a,b;
bool operator < (const data &h)const{return a<h.a;}
}s[maxn];
int n,m,nm,a[maxn],T,c[maxn],ans[maxn];
int mu[maxn],f[maxn],pr[maxn],lp;
const int mod=2147483647;
bool vis[maxn]; int getint(){
int w=0;bool q=0;
char c=getchar();
while((c>'9'||c<'0')&&c!='-') c=getchar();
if(c=='-') c=getchar(),q=1;
while(c>='0'&&c<='9') w=w*10+c-'0',c=getchar();
return q?-w:w;
} bool cmp(int x,int y){return f[x]<f[y];}
void add(int x,int y){if(y) while(x<=nm) c[x]+=y,x+=x&(-x);}
int sum(int x){
int t=0;
while(x) t+=c[x],x-=x&(-x);
return t;
} int main(){
File("a");
mu[1]=f[1]=a[1]=1; T=getint();
for(int i=1;s[i].b=i,i<=T;i++){
s[i].n=getint(),s[i].m=getint();
if(s[i].n>s[i].m) swap(s[i].n,s[i].m);
s[i].a=getint(); nm=max(nm,s[i].n);
}
for(int i=2;a[i]=i,i<=nm;i++){
if(!vis[i]) pr[++lp]=i,mu[i]=-1,f[i]=i+1;
for(int j=1;pr[j]*i<=nm;j++){
vis[pr[j]*i]=1;
if(i%pr[j]) mu[pr[j]*i]=-mu[i],f[pr[j]*i]=f[i]*f[pr[j]];
else{ f[pr[j]*i]=f[i]+(f[i]-f[i/pr[j]])*pr[j]; break;}
}
}
sort(s+1,s+T+1); sort(a+1,a+nm+1,cmp);
for(int i=1,now=1,b,la=0;i<=T;i++){
n=s[i].n; m=s[i].m; b=s[i].b;
while(now<=nm && f[a[now]]<=s[i].a){
for(int j=a[now];j<=nm;j+=a[now])
add(j,f[a[now]]*mu[j/a[now]]);
now++;
}
for(int j=1,nt,na;j<=n;j=nt+1){
nt=min(n/(n/j),m/(m/j)); na=sum(nt);
ans[b]+=(na-la)*(n/j)*(m/j); la=na;
}
}
for(int i=1;i<=T;i++) printf("%d\n",ans[i]&mod);
return 0;
}

BZOJ 3529 【SDOI2014】 数表的更多相关文章

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

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

  2. bzoj 3529 [Sdoi2014]数表(莫比乌斯反演+BIT)

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

  3. ●BZOJ 3529 [Sdoi2014]数表

    题链: http://www.lydsy.com/JudgeOnline/problem.php?id=3529 题解: 莫比乌斯反演. 按题目的意思,令$f(i)$表示i的所有约数的和,就是要求: ...

  4. 【刷题】BZOJ 3529 [Sdoi2014]数表

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

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

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

  6. bzoj 3529: [Sdoi2014]数表

    #include<cstdio> #include<iostream> #include<algorithm> #define M 200009 //#define ...

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

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

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

  9. 3529: [Sdoi2014]数表 - BZOJ

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

  10. 【BZOJ】3529: [Sdoi2014]数表

    题意:求 $$\sum_{i=1}^{n} \sum_{j=1}^{m} \sum_{d|(i, j)} d 且 (\sum_{d|(i, j)} d)<=a$$ n, m<=1e5,q次 ...

随机推荐

  1. 【BZOJ3437】小P的牧场 斜率优化

    [BZOJ3437]小P的牧场 Description 背景 小P是个特么喜欢玩MC的孩纸... 描述 小P在MC里有n个牧场,自西向东呈一字形排列(自西向东用1…n编号),于是他就烦恼了:为了控制这 ...

  2. mysql 5.7如何添加用户

    MySQL5.7 添加用户.删除用户与授权  转自:https://www.cnblogs.com/xujishou/p/6306765.html mysql -uroot -proot MySQL5 ...

  3. Thinkphp的cookie的怎么玩?

    在使用COOKIE的时候,首先要对COOKIE进行加密,加密方式采用:异位或的方式进行加密: // 异位或加密 1是加密 0 是解密 function encrytion($value,$type=0 ...

  4. mariadb安装配置

    CentOS 7安装MariaDB 详解以及相关配置 第一步:添加 MariaDB yum 仓库 首先在CentOS操作系统中/etc/yum.repos.d/目录下添加 MariaDB 的YUM配置 ...

  5. 利用Python进行端口扫描

    利用Python进行端口扫描 - Dahlhin - 博客园 https://www.cnblogs.com/dachenzi/p/8676104.html Python实现对一个网络段扫描及端口扫描 ...

  6. apt-get install 和 pip install的区别

    pip install apt-get install 源是pyPI 源是ubuntu仓库 对于同一个包,pyPI可以提供更多的版本以供下载 pip install安装的python包,可以只安装在当 ...

  7. linux route命令的使用详解 添加永久静态路由 tracert traceroute

    linux route命令的使用详解 添加永久静态路由  tracert  traceroute route -n    Linuxroute  print  Windows traceroute  ...

  8. The adidas NMD Singapore is one of the brands top selling

    Like pointed out, we've two adidas NMD Singapore releases using the first arriving Blue and Black as ...

  9. cocos代码研究(18)Widget子类Slider学习笔记

    理论基础 滑动条控件. 代码实践 实例: // Create the slider Slider* slider = Slider::create(); slider->loadBarTextu ...

  10. myeclips破解

    MyEclipse官方安装文件,下载地址 http://www.jb51.net/softs/150886.html破解补丁http://www.jb51.net/softs/150887.html ...