题目链接:数表

  我们一起来膜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. 二维坐标系极角排序的应用(POJ1696)

    Space Ant Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 3170   Accepted: 2029 Descrip ...

  2. PL/SQL Developer登入时候报ORA-12638

    在client安装目录,找到打开sqlnet.ora 在里面找到 SQLNET.AUTHENTICATION_SERVICES= (NTS)将其更改为: SQLNET.AUTHENTICATION_S ...

  3. Django - Jsonp、CORS

    一.同源策略 https://www.cnblogs.com/yuanchenqi/articles/7638956.html 同源策略(Same origin policy)是一种约定,它是浏览器最 ...

  4. Tensorflow中卷积的padding方式

    根据tensorflow中的Conv2D函数,先定义几个基本符号: 输入矩阵W*W,这里只考虑输入宽高相等的情况,如果不相等,推导方法一样 filter矩阵F*F,卷积核 stride值S,步长 输出 ...

  5. centos shell基础 alias 变量单引号 双引号 history 错误重定向 2>&1 jobs 环境变量 .bash_history source配置文件 nohup & 后台运行 cut,sort,wc ,uniq ,tee ,tr ,split, paste cat> 2.txt <<EOF 通配符 glob模式 发邮件命令mail 2015-4-8 第十二节课

    centos shell基础知识 alias  变量单引号 双引号   history 错误重定向 2>&1  jobs  环境变量 .bash_history  source配置文件 ...

  6. django基础之FBV与CBV,ajax序列化补充,Form表单

    目录: FBV与CBV ajax序列化补充 Form表单(一) 一.FBV与CBV 1.什么是FBV.CBV? django书写view时,支持两种格式写法,FBV(function bases vi ...

  7. POJ1144:Network(无向连通图求割点)

    题目:http://poj.org/problem?id=1144 求割点.判断一个点是否是割点有两种判断情况: 如果u为割点,当且仅当满足下面的1条 1.如果u为树根,那么u必须有多于1棵子树 2. ...

  8. STL学习笔记--算法

    关于STL算法需要注意的是: (1) 所有STL算法被设计用来处理一个或多个迭代器区间.第一个区间通常以起点和终点表示,至于其他区间,多数情况下只需提供起点即可,其终点可自动以第一区间的元素数推导出来 ...

  9. 工作记录之开发HRM项目总结

    开发HRM项目的步骤: 1:首先保留HRM项目中的两张表(Employee,Position)把这两张表中的数据内容复制到Operator-Portlet这个项目中,这两张表的service.xml配 ...

  10. (27)Cocos2d-x 3.0 Json用法

    Cocos2d-x 3.0 加入了rapidjson库用于json解析.位于external/json下. rapidjson 项目地址:http://code.google.com/p/rapidj ...