您的位置:首页 > 其它

BZOJ3994: [SDOI2015]约数个数和

2016-03-01 18:48 281 查看
很难想到。。

http://blog.codebursts.com/bzoj3994/

然后我是暴力求f的。。。

总体时间还是一样的

#include<cstdio>
#include<iostream>
using namespace std;
#define ll long long
const
int maxn=50001;
ll mu[maxn],pre[maxn];
bool check[maxn];
int prime[maxn],tot;
int f[maxn];

char c;
inline void read(int &a)
{
a=0;do c=getchar();while(c<'0'||c>'9');
while(c<='9'&&c>='0')a=(a<<3)+(a<<1)+c-'0',c=getchar();
}

int main()
{
int n,last,i,j,k,m;
for(n=1;n<maxn;n++)
{
i=1;
while(i<=n)
{
last=n/(n/i)+1;
last=min(n+1,last);
f
+=(last-i)*(n/i);
i=last;
}
}
mu[1]=1;pre[1]=1;
for(i=2;i<maxn;i++)
{
if(!check[i])
prime[++tot]=i,mu[i]=-1;
pre[i]=pre[i-1]+mu[i];
for(j=1;j<=tot;j++)
{
k=prime[j]*i;
if(k>maxn)break;
if(i%prime[j]==0){mu[k]=0;check[k]=true;break;}
check[k]=true,mu[k]=-mu[i];
}
}
int T;
ll ans;
read(T);
while(T--)
{
read(n),read(m);
if(m<n)swap(n,m);
i=1;
ans=0;
while(i<=n)
{
last=min(n/(n/i)+1,m/(m/i)+1);
last=min(n+1,last);
ans+=
(pre[last-1]-pre[i-1])*f[n/i]*f[m/i];
i=last;
}
printf("%lld\n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: