BZOJ-5244 最大真因数(min25筛)
题意:一个数的真因数指不包括其本身的所有因数,给定L,R,求这个区间的所有数的最大真因数之和。
思路:min25筛可以求出所有最小因子为p的数的个数,有可以求出最小因子为p的所有数之和。
那么此题就是对于所有素数因子,求它对应的和。
#include<bits/stdc++.h> using namespace std; #define ll unsigned long long const int maxn=150010; ll Sqr,vis[maxn],pri[maxn],sp[maxn],tot,m,id1[maxn],id2[maxn],g[maxn],h[maxn]; ll w[maxn]; void Sieve(int n) { tot=0; vis[1]=1; for(int i=2;i<=n;i++){ if(!vis[i]) pri[++tot]=i,sp[tot]=sp[tot-1]+i; for(int j=1;i*pri[j]<=n;j++){ vis[i*pri[j]]=1; if(i%pri[j]==0) break; } } } ll solve(ll n) { Sqr=sqrt(n); Sieve(Sqr); ll res=0; m=0; for(ll i=1,j;i<=n;i=j+1){ j=n/(n/i); w[++m]=n/i; if(w[m]<=Sqr) id1[w[m]]=m; else id2[n/w[m]]=m; if(w[m]&1) g[m]=(w[m]+1)/2*w[m]-1; else g[m]=w[m]/2*(w[m]+1)-1; } for(int j=1;j<=tot;j++) for(int i=1;i<=m&&pri[j]*pri[j]<=w[i];i++){ int k=(w[i]/pri[j]<=Sqr)?id1[w[i]/pri[j]]:id2[n/(w[i]/pri[j])]; g[i]=g[i]-pri[j]*(g[k]-sp[j-1]); if(i==1) res+=g[k]-sp[j-1]; } return res; } int main() { ll l,r; scanf("%llu%llu",&l,&r); printf("%llu\n",solve(r)-solve(l-1)); return 0; }
It is your time to fight!