HDU5382 GCD?LCM!
description
Let's define
Find S(n)\(\bmod 258280327\)
data range
\(T\le 10^5,n\le 10^6\)
solution
It's obvious that if we can calculate \(F(n)\) quickly, the problem is solved.
How to calculate \(F(n)\)?Let's define \(G(n)\) as follows:
then
Now the key point is to calculate \(G(n)\) quickly.
Let's define
then
To my surprise, \(t(n)\) is easy to calculate. In fact, \(t(n)=2^k\),in which \(k\) means the number of different prime factors in \(n\), because to make sure the condition \(\gcd(i,j)=1\) ,prime factors of the same kind should be assigned to either \(i\) or \(j\), which are only \(2\) ways, so for \(k\) different types of prime factors there are \(2^k\) ways .We can use linear sieve to find \(t(n)\) .Then, we can find \(G(n)\) through enumerating the multiples. After that, the problem is solved successfully .
time complexity
\(\mathcal O(n\ln n)\)
code
#include<cstdio>
using namespace std;
const int N=1e6+5,mod=258280327;
bool flag[N];int pr[N],pcnt,t[N],g[N],f[N];
inline int add(int x,int y){return x+y>=mod?x+y-mod:x+y;}
inline int dec(int x,int y){return x-y<0?x-y+mod:x-y;}
inline void pre()
{
t[1]=1;int n=N-5;
for(int i=2;i<=n;++i)
{
if(!flag[i])pr[++pcnt]=i,t[i]=2;
for(int j=1;j<=pcnt;++j)
{
int num=i*pr[j];if(num>n)break;
flag[num]=1;
if(i%pr[j])t[num]=add(t[i],t[i]);
else{t[num]=t[i];break;}
}
}
for(int i=1;i<=n;++i)
for(int j=i;j<=n;j+=i)
g[j]=add(g[j],t[j/i-1]);
for(int i=1;i<=n;++i)
f[i]=add(f[i-1],dec(2*i-1,g[i-1]));
for(int i=1;i<=n;++i)f[i]=add(f[i],f[i-1]);
}
int main()
{
pre();int T,n;scanf("%d",&T);
while(T-->0)scanf("%d",&n),printf("%d\n",f[n]);
return 0;
}
inspiration
It's of vital importance to consider combinatorial meaning while deduction .