做题记录1
BZOJ2005
首先我们将$2k+1$变换一下.显然有$2k+1=(2gcd{x,y})-1$这个事实.那么我们对$\gcd{x,y}$分区统计,方法参照http://www.contesthunter.org/record/43602我的SXBK题.
#include <cstdio>
int m,n,i,j,k;
long long fc[200000],ans;
int main(){
scanf("%d%d",&n,&m);
if(n>m){
n^=m;
m^=n;
n^=m;
}
for(i=n;i;--i){
fc[i]=((long long)(n/i))*(m/i);
for(j=2*i;j<=m;++j) fc[i]-=fc[j];
ans+=fc[i]*(2*i-1);
}
printf("%lld\n",ans);
return 0;
}
求给定$N$,$(x,y,z)=1,1\le x,y,z\le N$中$(x,y,z)$的对数.
我们考虑莫比乌斯反演.
http://quartergeek.com/eight-gcd-problems/ 讲得比较清楚.
#include <cstdio>
int pr[100000],pl,mu[2000000],i;
int prm[2000000],T,n;
int genMu(int n){
int i,j,k;
mu[1]=1;
for(i=2;i<=n;++i){
if(!prm[i]){
mu[i]=-1;
prm[i]=pr[pl++]=i;
}
for(j=0;j<pl&&(k=pr[j]*i)<=n;++j){
prm[k]=pr[j];
if(prm[i]==pr[j]){
mu[k]=0;
break;
}else{
mu[k]=-mu[i];
}
}
}
}
long long ans;
inline long long cb(long long a){
return a*a*a;
}
inline long long sq(long long a){
return a*a;
}
int main(){
genMu(1000000);
scanf("%d",&T);
while(T--){
scanf("%d",&n);
ans=3LL;
for(i=1;i<=n;++i) ans+=((long long)(mu[i]))*cb((long long)(n/i));
for(i=1;i<=n;++i) ans+=((long long)(mu[i]))*sq((long long)(n/i))*3LL;
printf("%lld\n",ans);
}
return 0;
}
BZOJ 1101 (POI)

浙公网安备 33010602011771号