bzoj 3994
来源:互联网 发布:电机选型软件 编辑:程序博客网 时间:2024/05/22 06:21
设
d(x) 为x 的约数个数,给定N,M ,求。∑i=1N∑j=1Md(ij)
Input
输入文件包含多组测试数据。
第一行,一个整数T ,表示测试数据的组数。
接下来的T 行,每行两个整数N,M 。
Output
T 行,每行一个整数,表示你所求的答案。
Sample Input
2
7 4
5 6
Sample Output
110
121
HINT
1≤N,M≤50000 1≤T≤50000
这题有个很屌的结论:
根据PoPoQQQ博客所说的,我们可以先证明这个式子的成立:
我们可以证明一下:我们对每个质数
代入得
我们转变枚举量,先枚举
于是
反演化为
转而枚举
再化一下就可得到
又有
于是我们发现
有了这个后再化简
#include<iostream>#include<cstdio>#include<cstdlib>using namespace std;typedef long long ll;#define maxn (50010)int f[maxn],mu[maxn],prime[maxn],n,m,tot; bool exist[maxn];inline int calc(int x){ int ret = 0; for (int i = 1,last;i <= x;i = last+1) { last = min(x,x/(x/i)); ret += (x/i)*(last-i+1); } return ret;}inline void ready(){ mu[1] = 1; for (int i = 2;i <= 50000;++i) { if (!exist[i]) { prime[++tot] = i; mu[i] = -1; } for (int j = 1;j <= tot&&prime[j]*i <= 50000;++j) { exist[i*prime[j]] = true; if (i % prime[j] == 0) { mu[i*prime[j]] = 0; break; } mu[i*prime[j]] = -mu[i]; } } for (int i = 1;i <= 50000;++i) mu[i] += mu[i-1],f[i] = calc(i);}inline ll work(){ if (n > m) swap(n,m); ll ret = 0; for (int i = 1,last;i <= n;i = last+1) { last = min(n,min(n/(n/i),m/(m/i))); ret += (ll)(mu[last]-mu[i-1])*((ll)f[n/i]*f[m/i]); } return ret;}int main(){ freopen("3994.in","r",stdin); freopen("3994.out","w",stdout); ready(); int T; scanf("%d",&T); while (T--) scanf("%d %d",&n,&m),printf("%lld\n",work()); fclose(stdin); fclose(stdout); return 0;}
0 0
- BZOJ 3994
- bzoj 3994
- [BZOJ ]
- BZOJ****-****
- BZOJ
- BZOJ
- BZOJ
- BZOJ
- BZOJ
- BZOJ
- BZOJ
- BZOJ
- BZOJ
- BZOJ
- bzoj
- bzoj
- BZOJ
- BZOJ
- 【BZOJ1012】最大数maxnumber,疯狂CE的线段树练习
- hdu acm 1115 Lifting the Stone(多边形重心)
- JSP实现文件上传【ie下有效】
- [maya学习笔记(2)] 物体的基本操作
- Activity—生命周期方法
- bzoj 3994
- POJ 3461 (KMP)
- 给已经建立的Xcode工程添加git版本控制
- Codeforces Round #256 (Div. 2) C. Painting Fence (DFS)
- Android开发者必知的5个开源库
- hdu 4389 数位DP 模板化代码 结合记忆化搜索优化
- junit
- 1
- KMP模板