标签:printf cst false .com blank ems style 维护 一个
由于这个证明过程太过长。。。推荐大家看这个大佬的博文,我就是看这个学会的 http://www.cnblogs.com/chenyang920/p/4811995.html
然后推荐一个求u数组更为有效的方式,利用线性筛选素数:
(例题是hdu1695)
#include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> using namespace std; typedef long long LL; bool v[1100000]; int prime[1100000],u[1100000]; void Mobius_inversion()//利用线性筛选素数来维护u { memset(v,false,sizeof(v)); int pr=0;u[1]=1; for(int i=2;i<=1000000;i++) { if(v[i]==false) { prime[++pr]=i; u[i]=-1;//本身是个质数,1个质数乘积 } for(int j=1;j<=pr,i*prime[j]<=1000000;j++) { v[i*prime[j]]=true; if(i%prime[j]==0) { u[i*prime[j]]=0;//除开质数的两种情况 break; } else u[i*prime[j]]=-u[i];//多了一个数的乘积,与前一个相反 } } } int main() { int T; scanf("%d",&T); Mobius_inversion(); for(int tt=1;tt<=T;tt++) { int a,b,c,d,k; scanf("%d%d%d%d%d",&a,&b,&c,&d,&k); if(k==0){printf("Case %d: 0\n",tt);continue;} b/=k;a/=k; d/=k;c/=k; if(b>d)swap(b,d); LL ans1=0; for(int i=1;i<=b;i++) ans1+=(LL)u[i]*(b/i)*(d/i);//带入 G(n) 的公式 有 F(1) = sigma(u[i]*(a/i)*(b/i)) (1<=i<=N) LL ans2=0; for(int i=1;i<=b;i++) ans2+=(LL)u[i]*(b/i)*(b/i); ans1-=ans2/2; printf("Case %d: %lld\n",tt,ans1); } return 0; }
标签:printf cst false .com blank ems style 维护 一个
原文地址:http://www.cnblogs.com/AKCqhzdy/p/7574398.html