BZOJ 2154 Crash的数字表格
跟着litble学套路
Solution
题目要求:
开始疯狂套路
0x00
首先化为常见的
的形式
0x01
然后枚举
0x02
接着将
变为
0x03
其次我们通过莫比乌斯函数的性质
将 转化为 ,即
0x04
下一步枚举
同时
也会变形,变为枚举
的倍数
假设 表示 的和,即
则原式为
0x05
设
,枚举
0x06
0x06
设
话说差点忘了
导致没推出来,想了好久
搞定
你以为这样就完了??
不存在的
还有一个反套路的点
如何求
?
显然是卷积的形式
那么它同时也是一个积性函数
所以按理来说应该可以线性筛
我们考虑新增一个质因数
原来处理出来了
若
若
代码如下:
#include <bits/stdc++.h>
using namespace std;
const int N = 10000005;
const int mod = 20101009;
int pri[N],tot,mu[N],n,m;
long long f[N];
long long s[N];
bool mark[N];
void get() {
mu[1]=1;
f[1]=1;
for(register int i=2;i<=10000000;++i) {
if(!mark[i]) {
pri[++tot]=i;
f[i]=1-i;
mu[i]=-1;
}
for(register int j=1;j<=tot && pri[j]*i<=10000000;++j) {
mark[i*pri[j]]=1;
if(i%pri[j]==0) {
f[i*pri[j]]=f[i];
break;
}
f[i*pri[j]]=f[i]*f[pri[j]]%mod;
mu[i*pri[j]]=-mu[i];
}
}
for(register int i=1;i<=10000000;++i) {
f[i]=((f[i]*i)%mod+f[i-1])%mod;
s[i]=(s[i-1]+i)%mod;
}
}
int main() {
get();
scanf("%d%d",&n,&m);
if(n>m) swap(n,m);
int pos=0,ans=0;
for(int i=1;i<=n;i=pos+1) {
pos=min(n/(n/i),m/(m/i));
ans=(ans+(f[pos]-f[i-1]+mod)%mod*s[n/i]%mod*s[m/i]%mod)%mod;
}
printf("%d\n",(ans+mod)%mod);
return 0;
}