HDU 4059 -容斥原理 +拉格朗日插值法
阿新 • • 發佈:2018-12-31
http://acm.hdu.edu.cn/showproblem.php?pid=4059
題意:
給出n,n<=1e8
求1到n裡,所有與n互質的數的四次方和
在這裡直接考慮,1+....n^4 減去 所有與n不互質的數的4次方
首先我們分解n的質因子,不會很多個
根據容斥原理,
我們列舉 質因子集合S,
那麼得到k=n/s,為s的倍數的個數,
而這部分數的四次方和的貢獻顯然是 k^4(1+2^4+3^4+......x^4)
然後容斥一下就好了,關鍵是推公式...233智商低 不會推,暴力拉格朗日插一下,
插出1+...n^4= (6*n^5+15n^4+3n^10)/30
求一下30的逆元就可以o1算出答案了。
#include<bits/stdc++.h> using namespace std; long long p[15]; int tot; long long n; const long long mod=1e9+7; const long long mm=233333335; long long get4(long long x) { long long tmp=x*x % mod; return tmp * tmp % mod; } long long f(long long x) { long long sum=0; long long tmp3=x * x % mod * x % mod; sum=(sum+tmp3*10) %mod;; long long tmp4=tmp3*x % mod; sum=(sum+tmp4*15 % mod) % mod; long long tmp5=tmp4*x % mod; sum=(sum+tmp5*6 % mod) % mod; sum=(sum-x+mod)% mod; long long ans=sum * mm % mod; return ans; } int main() { //freopen("in.txt","r",stdin); //freopen("output.txt","w",stdout); int tt; scanf("%d",&tt); while (tt--) { scanf("%lld",&n); long long nn=n; tot=0; for (long long i=2; i*i<=n; i++) { if (nn % i==0) { while (nn % i==0) nn/=i; p[tot++]=i; } } if (nn>1) p[tot++]=nn; /*for (int i=0; i<tot; i++) printf("%d ",p[i]);*/ long long ans=0; for (int state=1; state<(1<<tot); state++) { int num=0; long long pp=1; for (int i=0; i<tot; i++) if (state & (1<<i)) { num++; pp*=p[i]; } long long k=n/pp; long long tmp=get4(pp)*f(k) % mod; if (num % 2) ans+=tmp; else ans-=tmp; ans=ans % mod; } ans=f(n)-ans; ans=(ans+mod)%mod; printf("%lld\n",ans); } return 0; }