(题意还是很好理解的,这里就不再赘述,感觉这个题的知识量还是比较大的,比赛时看到那两个函数,以为是个简单的莫比乌斯反演,仔细读完题之后才发现不是。之后又推了一会,直接放弃了。
比赛结束后又花了不少时间研究公式的推导。)下面是公式的推导:
附代码:
#include <set> #include <map> #include <cmath> #include <stack> #include <queue> #include <vector> #include <string> #include <cstdio> #include <cstring> #include <sstream> #include <iomanip> #include <iostream> #include <algorithm> #define clr(str,x) memset(str,x,sizeof(str)) #define FRER() freopen("in.txt","r",stdin); #define FREW() freopen("out.txt","w",stdout); #define INF 0x3f3f3f3f #define maxn 100010 typedef long long int ll; using namespace std; bool vis[maxn]; ll prime[maxn]; int num=0; ll n; void init_prime() { memset(vis,false,sizeof(vis)); for(ll i=2; i<maxn; i++) { if(!vis[i]) prime[++num]=i; for(ll j=1; j<=num&&(i*prime[j]<maxn); j++) { vis[i*prime[j]]=true; if(i%prime[j]==0) break; } } } void solve() { ll ans1=1,ans2=1; ll N=n; for(int i=1; prime[i]*prime[i]<=n; i++) { if(n%prime[i]==0) { ll cnt=0; ll temp=prime[i]; while(n%prime[i]==0) { n/=prime[i]; temp*=prime[i]; cnt++; } ll a=(temp-1)/(prime[i]-1),b=temp+1,c=prime[i]+1; ans1*= ((a/c)*(b/c)*c + a%c*(b/c) + b%c*(a/c)); //计算(temp*temp-1)/(prime[i]*prime[i]-1)时防止溢出 ans2*=(cnt+1); } if(n==1) break; } if(n!=1) { ans1*=(n*n+1); ans2*=2; } printf("%lld\n",ans1-ans2*N); } int main() { //FRER() //FREW() init_prime(); int T; scanf("%d",&T); while(T--) { scanf("%lld",&n); solve(); } return 0; }
HDU - 5528(Count a × b )数论综合+公式推导
最新推荐文章于 2019-06-27 02:02:52 发布