SPOJ : DIVCNT2 - Counting Divisors (square)

\[f(n)=\sum_{d|n}\mu^2(d)\]

\[\begin{eqnarray*}
\sigma_0(n^2)&=&\sum_{d|n}f(d)\\
ans&=&\sum_{i=1}^n\sigma_0(i^2)\\
&=&\sum_{i=1}^n\sum_{d|i}\sum_{k|d}\mu^2(k)\\
&=&\sum_{k=1}^n\mu^2(k)G(\lfloor\frac{n}{k}\rfloor)
\end{eqnarray*}\]

其中

\[G(n)=\sum_{i=1}^n\lfloor\frac{n}{i}\rfloor\]

又因为

\[\sum_{i=1}^n\mu^2(i)=\sum_{i=1}^{\sqrt{n}}\mu(i)\lfloor\frac{n}{i^2}\rfloor\]

因此首先线性筛预处理出$n^{\frac{2}{3}}$内的所有答案,然后分段计算即可。

时间复杂度$O(Tn^{\frac{2}{3}})$。

#include<cstdio>
typedef long long ll;
const int N=100000010;
int T,M,tot,p[N/10],f[N];char v[N],mu[N],h[N];ll g[N],n,m,o,a[10010],old,now,ans,i,j;
inline ll F(ll n){
  if(n<M)return f[n];
  ll ret=0;
  for(ll i=1;i<=n/i;i++)ret+=n/i/i*mu[i];
  return ret;
}
inline ll G(ll n){
  if(n<M)return g[n];
  ll ret=0;
  for(ll i=1,j;i<=n;i=j+1){
    j=n/(n/i);
    ret+=n/i*(j-i+1);
  }
  return ret;
}
void init(){
  int i,j,k;
  for(mu[1]=g[1]=1,i=2;i<M;i++){
    if(!v[i])mu[i]=-1,g[i]=h[i]=2,p[tot++]=i;
    for(j=0;j<tot&&i*p[j]<M;j++){
      v[k=i*p[j]]=1;
      if(i%p[j]){
        mu[k]=-mu[i];
        g[k]=g[i]*2;
        h[k]=2;
      }else{
        g[k]=g[i]/h[i]*(h[i]+1);
        h[k]=h[i]+1;
        break;
      }
    }
  }
  for(i=1;i<M;i++)f[i]=f[i-1]+(mu[i]!=0),g[i]+=g[i-1];
}
int main(){
  scanf("%d",&T);
  for(o=1;o<=T;o++){
    scanf("%lld",&a[o]);
    if(a[o]>m)m=a[o];
  }
  if(m<=1000000)M=m;else{
    for(M=1;1LL*M*M*M<m;M++);
    M*=M;
  }
  init();
  for(o=1;o<=T;o++){
    n=a[o];
    ans=old=0;
    for(i=1;i<=n;i=j+1){
      now=F(j=n/(n/i));
      ans+=(now-old)*G(n/i);
      old=now;
    }
    printf("%lld\n",ans);
  }
  return 0;
}

  

时间: 2024-07-31 14:30:50

SPOJ : DIVCNT2 - Counting Divisors (square)的相关文章

Counting Divisors HDU - 6069

Counting Divisors HDU - 6069 题意:给定区间[a,b]和k,求xk有多少因子(x属于[a,b]),求和. 题解:http://blog.csdn.net/zlh_hhhh/article/details/76680641 a.b最大可达到1e12,但是b-a<1e6. 一开始愚蠢的一个一个分解然后去求有多少因子然后求和,范围那么大裸裸的超时啊! 可以枚举素数,对每一个素数,把区间内所有可以分解的进行分解. 最后再求和. 1 #include <bits/stdc++

HDU 6069 Counting Divisors —— 2017 Multi-University Training 4

Counting Divisors Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 524288/524288 K (Java/Others)Total Submission(s): 2599    Accepted Submission(s): 959 Problem Description In mathematics, the function d(n) denotes the number of divisors of p

hdu 6069 Counting Divisors(求因子的个数)

Counting Divisors Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 524288/524288 K (Java/Others)Total Submission(s): 3170    Accepted Submission(s): 1184 Problem Description In mathematics, the function d(n) denotes the number of divisors of

[Spoj]Counting Divisors (cube)

来自FallDream的博客,未经允许,请勿转载,谢谢. 设d(x)表示x的约数个数,求$\sum_{i=1}^{n}d(i^{3})$ There are 5 Input files. - Input #1: 1≤N≤10000, TL = 1s. - Input #2: 1≤T≤300, 1≤N≤10^8, TL = 20s. - Input #3: 1≤T≤75, 1≤N≤10^9, TL = 20s. - Input #4: 1≤T≤15, 1≤N≤10^10, TL = 20s. -

SPOJDIVCNT2: Counting Divisors(莫比乌斯反演)

http://acm.tzc.edu.cn/acmhome/vProblemList.do?method=problemdetail&oj=SPOJ&pid=DIVCNT2 给出n求 其中是除数函数,0代表0次方. 1 #include<algorithm> 2 #include<cstdio> 3 #include<cmath> 4 #include<cstring> 5 #include<iostream> 6 #define

【区间筛】2-17多校训练四 HDU6069 Counting Divisors

http://acm.hdu.edu.cn/showproblem.php?pid=6069 [题意] 给定l,r,k,求 d(n)是n的因子个数 [思路] [Accepted] 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<string> 5 #include<cmath> 6 #include<algorithm> 7 #include

第四场 hdu 6069 Counting Divisors (逆向思维)

http://acm.hdu.edu.cn/showproblem.php?pid=6069 题目大意:求 i 从 l 到 r 中 i 的k次方的因子数之和. 解题思路:我们可以知道一个数有因子,则这个数的因子一定是若干个质数因子排列组合得到的.我们首先要得到10^6中的素数,然后它的因子数量是 相同质因子数量+1 的乘积,所以我们能够想到从 l 到 r 枚举每一个i得到其 相同质因子数量+1 的乘积 的累加和.但是这样在枚举时会发现有一些质数是并不是所求的 i 的因子,所以我们应该反过来考虑,

HDU 6069 Counting Divisors(唯一分解定理+因子数)

http://acm.hdu.edu.cn/showproblem.php?pid=6069 题意: 思路: 根据唯一分解定理,$n={a_{1}}^{p1}*{a2_{}}^{p2}...*{a_{m}}^{pm}$,那么n的因子数就是 n的k次方也是一样的,也就是p前面乘个k就可以了. 先打个1e6范围的素数表,然后枚举每个素数,在[ l , r ]寻找该素数的倍数,将其分解质因数. 到最后如果一个数没有变成1,那就说明这个数是大于1e6的质数.(它就只有0和1两种选择) 1 #includ

SPOJ 12943. Counting, dp ,巧妙

Given integers N and M, output in how many ways you can take N distinct positive integers such that sum of those integers is <= M. Since result can be huge, output it modulo 1000000007 (10^9 + 7) N <= 20 M <= 100000 Input First line of input is n