码迷,mamicode.com
首页 > 其他好文 > 详细

hdu 1695 GCD 欧拉函数+容斥

时间:2015-02-11 22:05:12      阅读:189      评论:0      收藏:0      [点我收藏+]

标签:欧拉函数   容斥   

题意:给定a,b,c,d,k

            x属于[1 , c],y属于[1 , d],求满足gcd(x,y)=k的对数。其中<x,y>和<y,x>算相同。

思路:不妨设c<d,x<=y。问题可以转化为x属于[1,c / k ],y属于[1,d/k ],x和y互质的对数。

            那么假如y<=c/k,那么对数就是y从1到c/k欧拉函数的和。如果y>c/k,就只能从[ c/k+1 , d ]枚举,然后利用容斥。详见代码:

/*********************************************************
  file name: hdu1695.cpp
  author : kereo
  create time:  2015年02月11日 星期三 18时08分43秒
*********************************************************/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<set>
#include<map>
#include<vector>
#include<stack>
#include<cmath>
#include<string>
#include<algorithm>
using namespace std;
typedef long long ll;
const int sigma_size=26;
const int N=100+50;
const int MAXN=100000+50;
const int inf=0x3fffffff;
const double eps=1e-8;
const int mod=1000000000+7;
#define L(x) (x<<1)
#define R(x) (x<<1|1)
#define PII pair<int, int>
#define mk(x,y) make_pair((x),(y))
int primecnt,factcnt;
int prime[MAXN],euler[MAXN],factor[N][2];
void getprime(){
    primecnt=0;
    memset(prime,0,sizeof(prime));
    for(int i=2;i<MAXN;i++){
        if(!prime[i])
            prime[primecnt++]=i;
        for(int j=0;j<primecnt && prime[j]<=MAXN/i;j++){
            prime[prime[j]*i]=1;
            if(i%prime[j] == 0)
                break;
        }
    }
}
void geteuler(){
    memset(euler,0,sizeof(euler));
    euler[1]=1;
    for(int i=2;i<MAXN;i++){
        if(!euler[i]){
            for(int j=i;j<MAXN;j+=i){
                if(!euler[j])
                    euler[j]=j;
                euler[j]=euler[j]/i*(i-1);
            }
        }
    }
}
int getfactor(int x){
    factcnt=0;
    for(int i=0;prime[i]<=x/prime[i];i++){
        factor[factcnt][1]=0;
        if(x%prime[i] == 0){
            factor[factcnt][0]=prime[i];
            while(x%prime[i] == 0){
                x/=prime[i];
                factor[factcnt][1]++;
            }
            factcnt++;
        }
    }
    if(x!=1){
        factor[factcnt][0]=x;
        factor[factcnt++][1]++;
    }
    return factcnt;
}
int solve(int n,int m){
    int ans=0;
    getfactor(m);
    for(int i=1;i<(1<<factcnt);i++){
        int cnt=0,res=1;
        for(int j=0;j<factcnt;j++){
            if(i&(1<<j)){
                cnt++;
                res*=factor[j][0];
            }
        }
        if(cnt & 1)
            ans+=n/res;
        else 
            ans-=n/res;
    }
    return n-ans;
}
int main(){
    int T,kase=0;
    scanf("%d",&T);
    getprime();
    geteuler();
    while(T--){
        printf("Case %d: ",++kase);
        int a,b,c,d,k;
        scanf("%d%d%d%d%d",&a,&b,&c,&d,&k);
        if(k == 0 || k>b || k>d){
            printf("0\n");
            continue;
        }
        if(b>d)
            swap(b,d);
        b/=k; d/=k;
        ll ans=0;
        for(int i=1;i<=b;i++)
            ans+=euler[i];
        for(int i=b+1;i<=d;i++)
            ans+=solve(b,i);
        printf("%I64d\n",ans);
    }
	return 0;
}


hdu 1695 GCD 欧拉函数+容斥

标签:欧拉函数   容斥   

原文地址:http://blog.csdn.net/u011645923/article/details/43737013

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!