One is more malignant than the other
[51 nod 1227] average least common multiple
It's actually asking for
So we just need to find the function \ (Ans(n) \)
set up
And we know
We also know
Where \ (* \) represents Dirichlet convolution
So become
Bring into the whole formula
Consider taking \ (e \) out, then only if \ (i \) is equal to 1, there will be contribution. There are N 1s in total, so the total contribution is n
The problem is transformed into finding the prefix sum of \ (i\times \varphi(i) \). We consider a \ (id(n)=n \) on the volume, which can be simplified to obtain \ (n^2 \), and just go to the Du educational sieve
Complexity \ (O(n^{\frac{2}{3}) \)
#include<bits/stdc++.h> using namespace std; const int N = 1e6+7; typedef long long LL; const LL mod = 1e9+7; LL phi[N]; LL f[N]; int v[N],prime[N],tot=0; LL Pow(LL a,LL b) { LL res=1; while(b) { if(b&1) res=1ll*res*a%mod; a=1ll*a*a%mod; b>>=1; } return res; } LL inv6=Pow(6,mod-2); LL inv2=Pow(2,mod-2); LL sqr(LL n) { n%=mod; return n*(n+1)%mod*(2*n+1)%mod*inv6%mod; } LL sum(LL n) { return 1ll*(1+n)*n%mod*inv2%mod; } void init(int n) { phi[1]=1; for(int i=2;i<=n;i++) { if(!v[i]) { v[i]=i; prime[++tot]=i; phi[i]=i-1; } for(int j=1;j<=tot;j++) { if(prime[j]>v[i]||i*prime[j]>n) break; v[i*prime[j]]=prime[j]; if(i%prime[j]==0) { phi[i*prime[j]]=phi[i]*prime[j]; break; } else phi[i*prime[j]]=phi[i]*(prime[j]-1); } } for(int i=1;i<=n;i++) phi[i]=(phi[i-1]+phi[i]*i%mod)%mod; } unordered_map<LL,LL> s,vis; LL Sum(LL n) { if(n<=1e6) return phi[n]; if(vis[n]) return s[n]; LL res=sqr(n); LL l=2,r; for(;l<=n;l=r+1) { r=(n/(n/l)); res=(res-(sum(r)-sum(l-1)+mod)%mod*Sum(n/l)%mod+mod)%mod; } vis[n]=1; s[n]=res; return res; } LL calc(LL n) { LL res=n; LL l=1,r; for(;l<=n;l=r+1) { r=n/(n/l); res=(res+1ll*(r-l+1)%mod*Sum(n/l)%mod)%mod; } return res*inv2%mod; } int main() { freopen("minave.in","r",stdin); freopen("minave.out","w",stdout); init(1e6); LL a,b; cin>>a>>b; cout<<(calc(b)-calc(a-1)+mod)%mod; return 0; }
SP20173 DIVCNT2 - Counting Divisors (square)
Consider analyzing the properties of \ (\ sigma(n^2) \) first
Obviously, this is an integral function. We consider each quality factor separately
\(\sigma((p^k)^2)=2*k+1=k+(k+1)=\sigma(p^k)+\sigma(p^{k-1})\)
Let's continue to observe, \ (P ^ k \)\ (p^{k-1}\)?
That is, the power of \ (p_k \) divided by their prime factor is 0 or 1
So is there anything related to the index?
Yes, it's \ (\ mu \), but \ (\ mu \) has a negative number. What should I do
Yes, just add a square
In fact, as we analyzed, \ (\ sigma(n^2)=\sum_{d|n}\sigma(d)\mu^2(\frac{n}{d})\)
Of course, and \ (\ sigma(n^2)=\sum_{d|n}\sigma(\frac{n}{d})\mu^2(d) \) is the same
Don't turn around
This thing can be divided into blocks. Now the problem becomes to get
\(\ mu^2(n) \) and \ (\ sigma(n) \) prefixes and
According to some knowledge of tolerance and exclusion, we can get
\(\sum_{i=1}^n\mu^2(i)=\sum_{i=1}^{\sqrt n}\mu(i)\lfloor \frac{n}{d^2}\rfloor\)
This can be achieved by dividing the whole into blocks \ (O(\sqrt n) \)
And there is a well-known formula
\(\sum_{i=1}^n\sigma(i)=\sum_{i=1}^n\lfloor \frac{n}{i}\rfloor\)
The proof is to consider how many multiples each number has in n numbers
This can also be divided into blocks to achieve \ (O(\sqrt n) \)
But the two \ (n \) are \ (O(n) \)
Let's consider preprocessing the prefix and sum of the first \ (n^{\frac{2}{3}} \) items of \ (\ mu^2(n) \) and \ (\ sigma(n) \), and call it directly when asking
The complexity is similar to that of Du Jiao sieve (O(n^{\frac{2}{3}) \)
Of course, this question is poisonous
Its \ (n \) is \ (10 ^ {12} \), and the preprocessing should be processed to \ (10 ^ 8 \)
Therefore, not only the space is large, but also the constant is large
This code can't run on SPOJ
#include<bits/stdc++.h> using namespace std; const int N = 5e7+5; const int M = 1e7+7; typedef long long LL; LL d[N]; int mu[N]; int t[N]; bool v[N]; int prime[M],tot=0; void init(int n) { mu[1]=1; d[1]=1; for(int i=2;i<=n;i++) { if(!v[i]) { v[i]=1; prime[++tot]=i; d[i]=2; mu[i]=-1; t[i]=2; } for(int j=1;j<=tot;j++) { if(i*prime[j]>n) break; v[i*prime[j]]=1; if(i%prime[j]==0) { t[i*prime[j]]=t[i]+1; d[i*prime[j]]=d[i]/t[i]*(t[i]+1); mu[i*prime[j]]=0; break; } t[i*prime[j]]=2; d[i*prime[j]]=d[i]*d[prime[j]]; mu[i*prime[j]]=mu[i]*mu[prime[j]]; } } for(int i=1;i<=n;i++) { d[i]+=d[i-1]; t[i]=t[i-1]+abs(mu[i]); } } LL R; LL SumU(LL n) { if(n<=R) return t[n]; LL res=0; for(LL i=1;i*i<=n;i++) res=(res+mu[i]*(n/i/i)); return res; } LL SumD(LL n) { if(n<=R) return d[n]; LL res=0; LL l=1,r; for(;l<=n;l=r+1) { r=n/(n/l); res=res+(r-l+1)*(n/l); } return res; } void solve(LL n) { LL res=0; LL l=1,r; LL last=0; LL m=sqrt(n); for(LL i=1;i<=m;i++) if(mu[i]!=0) res=res+SumD(n/i); l=m+1;last=SumU(m); for(;l<=n;l=r+1) { r=n/(n/l); LL now=SumU(r); res=(res+(now-last)*SumD(n/l)); last=now; } printf("%lld\n",res); } LL a[20000]; LL INF = 1e12; int main() { freopen("a.in","r",stdin); freopen("a.out","w",stdout); int T; cin>>T; LL r; for(int i=1;i<=T;i++) { scanf("%lld",&a[i]); r=max(r,a[i]); } if(r<=10000) R=10000; else R=N-10; init(R); for(int i=1;i<=T;i++) solve(a[i]); return 0; }
[51nod1222] least common multiple count
Or first make the form of prefix subtraction
Turn problems into problems
Found that the maximum of \ (k \) will not exceed \ (\ sqrt(n) \)
therefore
Consider enumerating \ (k \) to calculate the following values
Observe the upper indexes of the last three items
You will find that if \ (a\geq \lfloor \frac{n}{k} \rfloor \), the following formula is 0
Similarly, the upper index of \ (i,j \) can be constrained by the latter
So the back part is equal to
Let's consider forcing \ (d\leq i \leq j \) and multiplying it by a coefficient
Consider different \ (d,i,j \) states
1: \ (d,d,d \), that is, three equal ones. Add one to the enumerated legal d
2: \ (d,i,i \), that is, the last two are equal. Calculate the number of legal \ (d,i \) multiplied by 3
3: \ (d,d,i \) is similar to 2
4: \(d,i,j\)
It is found that \ (d \) only needs to enumerate to the third root of N, and i only needs to enumerate to the square root of n
The total complexity is similar to that of Du Jiao sieve, which is \ (O(n^{\frac{2}{3}) \), and its coefficient is 6
You can calculate it later
#include<bits/stdc++.h> using namespace std; typedef long long LL; const LL N =1e6+7; LL mu[N],v[N]; LL prime[N],tot=0; void init(LL n) { mu[1]=1; for(LL i=2;i<=n;i++) { if(!v[i]) { v[i]=i; mu[i]=-1; prime[++tot]=i; } for(LL j=1;j<=tot;j++) { if(prime[j]>v[i]||i*prime[j]>n) break; v[i*prime[j]]=prime[j]; if(i%prime[j]==0) { mu[i*prime[j]]=0; break; } mu[i*prime[j]]=mu[i]*mu[prime[j]]; } } } LL S(LL n) { LL res=0; for(LL k=1;k*k<=n;k++) { if(!mu[k]) continue; LL cnt=0; LL limit=n/(k*k); for(LL i=1;i*i*i<=limit;i++) { for(LL j=i+1;i*j*j<=limit;j++) cnt+=(LL)(limit/(i*j)-j)*6+3;//i,j,k+i,j,j cnt+=(LL)(limit/(i*i)-i)*3;//i,i,j cnt++;//i,i,i } res=res+mu[k]*cnt; } return (res+n)/2; } int main() { freopen("a.in","r",stdin); freopen("a.out","w",stdout); init(1e6); LL l,r; cin>>l>>r; cout<<S(r)-S(l-1); return 0; }
[51nod1220] sum of divisors
seek
Where \ (\ sigma(n) \) represents the sum of factors of \ (n \)
First, there is lemma
\(\sigma(ij)=\sum_{x|i}\sum_{y|j}[gcd(x,y)==1]\frac{xj}{y}\)
The proof is similar to the approximate number and sum of SDOI, which will not be repeated
Direct Mo counter
Set \ (f(n)=\sum_{i=1}^n\sum_{j=1}^{\lfloor \frac{n}{i}\rfloor}i\),\(g(n)=\sum_{i=1}^ni\lfloor \frac{n}{i} \rfloor\)
Consider the relationship between \ (f(n) \) and \ (g(n) \)
You will find that \ (g(n) \) actually multiplies the weight of each number \ (i \) in \ (f(n) \) by the number of times it appears
Therefore, the two formulas are equivalent, and the problem is further transformed into
We only need to find the prefix sum of \ (g(n) \) to divide the blocks
Then you will find \ (\ sum {I = 1} ^ n \ sigma (I) = \ sum_ {i=1}^ni\lfloor \frac{n}{i} \rfloor=g(n)\)
So \ (g(n)=\sum_{i=1}^n\sigma(i)\)
As we all know, \ (\ sigma(n) \) is an integral function, which can be obtained by linear sieve
Similar to Du Jiao sieve, preprocess the prefix sum of division \ (n^{\frac{2}{3}} \), and the remaining division can be done by block violence, which can achieve \ (O(n^{\frac{2}{3}) \)
Don't forget that there is one \ (\ mu(d)d \) left at the end and one \ (id(n)=n \) on the volume, so you can teach the screen
#include<bits/stdc++.h> using namespace std; const int N = 1e6+7; typedef long long LL; int mu[N]; LL f[N]; int v[N],prime[N],tot=0; const int mod = 1e9+7; LL d[N],t[N],g[N]; void init(LL n) { mu[1]=1; d[1]=1; for(int i=2;i<=n;i++) { if(!v[i]) { v[i]=i; prime[++tot]=i; mu[i]=-1; d[i]=i+1; g[i]=i; t[i]=i+1; } for(int j=1;j<=tot;j++) { if(prime[j]>v[i]||i*prime[j]>n) break; v[i*prime[j]]=prime[j]; if(i%prime[j]==0) { g[i*prime[j]]=g[i]*prime[j]; t[i*prime[j]]=t[i]+g[i*prime[j]]; d[i*prime[j]]=d[i]/t[i]*t[i*prime[j]]; mu[i*prime[j]]=0; break; } else { mu[i*prime[j]]=mu[i]*mu[prime[j]]; d[i*prime[j]]=d[i]*d[prime[j]]; g[i*prime[j]]=prime[j]; t[i*prime[j]]=1+prime[j]; } } } for(int i=1;i<=n;i++) { f[i]=(f[i-1]+mu[i]*i%mod+mod)%mod; d[i]=(d[i]+d[i-1])%mod; } } unordered_map<LL,LL> vis,s; LL Sum(LL n) { if(n<=1e6) return f[n]; if(vis[n]) return s[n]; LL res=1; LL l=2,r; for(;l<=n;l=r+1) { r=n/(n/l); res=(res-1ll*(l+r)*(r-l+1)/2%mod*Sum(n/l)%mod+mod)%mod; } vis[n]=1; s[n]=res; return res; } LL D(LL n) { if(n<=1e6) return d[n]; LL l=1,r; LL res=0; for(;l<=n;l=r+1) { r=n/(n/l); res=(res+(l+r)*(r-l+1)/2%mod*(n/l)%mod)%mod; } return res; } int main() { freopen("a.in","r",stdin); freopen("a.out","w",stdout); init(1e6); LL n; cin>>n; LL res=0; LL l=1,r; for(;l<=n;l=r+1) { r=n/(n/l); LL val=D(n/l); res=(res+(Sum(r)-Sum(l-1)+mod)%mod*val%mod*val%mod)%mod; } cout<<res; return 0; }
[51nod1584] sum of weighted divisors
seek
We know that the answer matrix of this \ (n*n \) is symmetric, so the answer is
Look at the first half first
Similar to the previous question
\(\sigma(ij)=\sum_{x|i}\sum_{y|j}[gcd(x,y)==1]\frac{xj}{y}\)
Bring in formula
Set \ (f(n)=n\sigma(n)\sum_{i=1}^n\sigma(i)\)
We can preprocess the prefix sum divided by \ (\ sigma(n) \), so that we can quickly calculate \ (f(i) \)
However, the number of inquiries is very large, and we \ (O(1) \) need to answer
Therefore, continue to simplify
This formula can be calculated by the harmonic series \ (O(n\log n) \), and then the prefix sum can be calculated to query \ (O(1) \)
Then look at the second half
The problem is dealing with the prefix and of \ (\ sigma(n^2) \)
This can also be screened out by linear sieve. After all, this is an integral function
#include<bits/stdc++.h> using namespace std; typedef long long LL; const LL N = 1e6+7; const LL mod =1e9+7; LL d[N],t[N],p[N]; LL sd[N],st[N],sp[N]; LL s[N],g[N]; LL mu[N]; LL v[N],prime[N],tot=0; LL Pow(LL a,LL b) { LL res=1; while(b) { if(b&1) res=1ll*res*a%mod; a=1ll*a*a%mod; b>>=1; } return res; } LL inv(LL n) { return Pow(n,mod-2); } LL f[N]; void init(LL n) { mu[1]=1; sd[1]=1; d[1]=1; for(LL i=2;i<=n;i++) { if(!v[i]) { v[i]=i; prime[++tot]=i; mu[i]=-1; d[i]=i+1; t[i]=i+1; p[i]=i; sd[i]=(1+i+(LL)i*i%mod)%mod; st[i]=(1+i+(LL)i*i%mod)%mod; sp[i]=(LL)i*i%mod; } for(LL j=1;j<=tot;j++) { if(v[i]<prime[j]||i*prime[j]>n) break; LL k=i*prime[j]; v[i*prime[j]]=prime[j]; if(i%prime[j]==0) { mu[k]=0; p[k]=p[i]*prime[j]%mod; t[k]=(t[i]+p[k])%mod; d[k]=d[i]*inv(t[i])%mod*t[k]%mod; sp[k]=sp[i]*prime[j]%mod*prime[j]%mod; st[k]=(st[i]+sp[i]*prime[j]%mod+sp[k])%mod; sd[k]=(sd[i]*inv(st[i])%mod*st[k])%mod; break; } else { mu[k]=mu[i]*mu[prime[j]]; p[i*prime[j]]=prime[j]; t[i*prime[j]]=1+prime[j]; d[i*prime[j]]=d[i]*d[prime[j]]%mod; sp[i*prime[j]]=prime[j]*prime[j]%mod; st[i*prime[j]]=(1+prime[j]+prime[j]*prime[j]%mod)%mod; sd[i*prime[j]]=sd[i]*sd[prime[j]]%mod; } } } for(LL i=1;i<=n;i++) s[i]=(d[i]+s[i-1])%mod; for(LL i=1;i<=n;i++) sd[i]=(sd[i-1]+i*sd[i]%mod)%mod; for(LL i=1;i<=n;i++) g[i]=1ll*i*d[i]%mod*s[i]%mod; for(LL d=1;d<=n;d++) for(LL T=d;T<=n;T+=d) f[T]=(f[T]+mu[d]*d%mod*d%mod*g[T/d]%mod+mod)%mod; for(LL i=1;i<=n;i++) f[i]=(f[i-1]+f[i])%mod; } LL calc(LL n) { return (2ll*f[n]%mod-sd[n]+mod)%mod; } int main() { freopen("a.in","r",stdin); freopen("a.out","w",stdout); init(1e6); LL T; cin>>T; int ca=0; while(T--) { LL n; ca++; scanf("%lld",&n); printf("Case #%d: %lld\n",ca,calc(n)); } return 0; }