@y20070316
2017-04-08T14:49:12.000000Z
字数 2550
阅读 1515
专题练习 初等数论 杜教筛
#include <cstdio>#include <map>using namespace std;#define F(i,a,b) for (int i=(a);i<=(b);i++)#define LL long longconst int N=5000000;int v[N+5],pri[500000],tot;int mu[N+5];map<LL,LL> s;LL Query(LL n) {if (n<=N) return mu[n];if (s.count(n)) return s[n];LL ans=1;for (LL l=2,r;l<=n;l=r+1) {r=n/(n/l);ans-=(r-l+1)*Query(n/l);}return s[n]=ans;}int main(void) {#ifndef ONLINE_JUDGEfreopen("sdchr.in","r",stdin);#endifv[1]=mu[1]=1;F(i,2,N) {if (!v[i]) pri[++tot]=i,mu[i]=-1;F(j,1,tot) {if (i*pri[j]>N) break;v[i*pri[j]]=1;if (i%pri[j]!=0) mu[i*pri[j]]=-mu[i]; else break;}}F(i,1,N) mu[i]+=mu[i-1];LL a,b; scanf("%lld%lld",&a,&b);LL ansL=Query(a-1);printf("%lld\n",Query(b)-ansL);return 0;}
实现:
int 类型的 a,b ,有: plus(a,b): (a+b)%L multiply(a,b): 1LL*a*b%L long long ((LL)a-b+c-1LL*d*e%L)%L long long 类型的乘法,先将 long long 转化为 int ,中间加空格。
inline int binom2(LL n) {return (n%2==0) ? ((n/2)%L) * ((n+1)%L) %L : ((n+1)/2)%L * (n%L) %L;}
总之如果 A 和 B 是两个运算的整体,那么写成 (A) * (B) % L 。
#include <cstdio>#include <map>using namespace std;#define F(i,a,b) for (int i=(a);i<=(b);i++)#define LL long longconst int N=5000000;const int L=(int)1e9+7;int v[N+5],pri[500000],tot;int phi[N+5];map<LL,int> s;int Query(LL n) {if (n<=N) return phi[n];if (s.count(n)) return s[n];int ans=( n%2==0 ? (n/2)%L * ((n+1)%L) %L : ((n+1)/2%L) * (n%L) %L );for (LL l=2,r;l<=n;l=r+1) {r=n/(n/l);ans=(ans- ((r-l+1)%L) * Query(n/l) %L )%L;}return s[n]=(ans+L)%L;}int main(void) {#ifndef ONLINE_JUDGEfreopen("sdchr.in","r",stdin);#endifv[1]=phi[1]=1;F(i,2,N) {if (!v[i]) pri[++tot]=i,phi[i]=i-1;F(j,1,tot) {if (i*pri[j]>N) break;v[i*pri[j]]=1;if (i%pri[j]!=0) phi[i*pri[j]]=phi[i]*phi[pri[j]];else { phi[i*pri[j]]=phi[i]*pri[j]; break; }}}F(i,1,N) phi[i]=(phi[i]+phi[i-1])%L;LL n; scanf("%lld",&n);printf("%d\n",Query(n));return 0;}