具体可以参考http://www.cnblogs.com/kane0526/archive/2013/03/14/2795446.html
写的挺好的。。
先是比较基础的,
int prime[100];
LL gao(LL n,LL m){
int pn=0;
for(LL i=2;i*i<=m;++i){//求一个数的质因数的模板
if(m%i)continue;
while(m%i==0)m/=i;
prime[pn++]=i;
}
if(m!=1)prime[pn++]=m;
int g=(1<<pn);
LL ret=0;
for(LL i=1;i<g;++i){
int tmp=i,k=0,num=1;
for(int j=0;j<pn;++j){
if(tmp&1)k++,num*=prime[j];
tmp>>=1;
}
if(k&1)ret+=n/num;
else ret-=n/num;
}
return n-ret;
}
int main(){
int cas=0;
int T;sf("%d",&T);
while(T--){
LL a,b,n;
sf("%lld%lld%lld",&a,&b,&n);
LL ans=gao(b,n)-gao(a-1,n);
pf("Case #%d: %lld\n",++cas,ans);
}
}
参考http://blog.csdn.net/acm_cxlove/article/details/7877440
然后是hdu1796的应用:其实就只是要看出
发现如果A1/B1=A2/B2那么就有一棵树看不到,所以就是找出Ai/Bi有多少种。
再可以发现A/B中,如果A,B有大于1的公约数,则A=A’*D B=B’*D,那么A/B=A’/B’,也就是存在另外一组数和这种相等,则问题转换成有多少对互质的数,枚举i,从1-M中找与i互质的数,其中1<=i<=N。
怕手生,写了个dfs版的,
居然没有快。。J
int n,m;
int prime[8];
LL ret;
int pn;
void dfs(int pos,LL now ,int step){
if(pos>pn)return ;
if(step&1)ret+=m/now;
else ret-=m/now;
for(int i=pos+1;i<pn;++i){
dfs(i,now*prime[i],step+1);
}
}
LL gao(int n,int m){
pn=0;
for(int i=2;i*i<=m;++i){//求一个数的质因数的模板
if(m%i)continue;
while(m%i==0)m/=i;
prime[pn++]=i;
}
if(m!=1)prime[pn++]=m;
ret=0;
for(int i=0;i<pn;++i){
dfs(i,prime[i],1);
}
return n-ret;
}
int main(){
int T;sf("%d",&T);
while(T--){
sf("%d%d",&n,&m);
LL ans=0;
for(int i=1;i<=n;++i){
ans+=gao(m,i);
}
pf("%lld\n",ans);
}
}
然后第三题也差不多。。。
const int maxn=100005;
bool color[maxn];
int f[maxn], phi[maxn];
int prime[maxn];
void Eular() //欧拉函数
{
phi[1]=1;
int k, num=0;
memset(color,false,sizeof(color));
for(int i=2; i<maxn; i++)
{
if(!color[i])
{
f[num++]=i;
phi[i]=i-1;
}
for(int j=0; j<num&&(k=i*f[j])<maxn; j++)
{
color[k]=true;
if(i%f[j]==0)
{
phi[k]=phi[i]*f[j]; break;
}
else
phi[k]=phi[i]*(f[j]-1);
}
}
}
LL gao(int n,int m){
int pn=0;
for(int i=2;i*i<=m;++i){
if(m%i)continue;
while(m%i==0)m/=i;
prime[pn++]=i;
}
if(m!=1)prime[pn++]=m;
LL ret=0;
int g=(1<<pn);
for(int i=1;i<g;++i){
int tmp=i,k=0,num=1;
for(int j=0;j<pn;++j){
if(tmp&1)k++,num*=prime[j];
tmp>>=1;
}
if(k&1)ret+=n/num;
else ret-=n/num;
}
return n-ret;
}
int main(){
int T;sf("%d",&T);
int cas=0;
Eular();
while(T--){
ans=0;
sf("%d%d%d%d%d",&a,&b,&c,&d,&k);
if(k==0||k>b||k>d){pf("Case %d: 0\n",++cas);continue ;}
b/=k;d/=k;
if(b>d)swap(b,d);
for(int i=1;i<=b;++i){
ans+=phi[i];
}
for(int i=b+1;i<=d;++i){
ans+=gao(b,i);
}
pf("Case %d: %lld\n",++cas,ans);
}
}