HDU-4135 欧拉函数+容斥

题目传送门: http://acm.hdu.edu.cn/showproblem.php?pid=4135


题意:输入三个数a,b,n,求[a,b]之间与n互质的个数


这题可以转化成求[1,b]内与n互质的个数减去[1,a]内与n互质的个数。

而[1,x]内与n互质的数可以转化成x-[1,x]内不与n互质的数。

接下来就是求[1,x]与n不互质的数,先找出n以内的质因数保存在数组a里,如果没有就将n保存在数组a里。

然后用 n/a1 + n/a2 +.... 但有一个很明显的问题是会有重复的元素加进去,这就需要用到容斥定理了,将多余的给减掉。

公式是 n/a1 +n/a2 + .... -n/(a1*a2) .....+ n/(a1*a2*a3)....

可以观察出规律,奇数个质因数相乘的项加进去,偶数个质因数相乘的项减去。

这样就解决了


代码如下:

#include
using namespace std;

#define   lowbit(x)     x&(-x)
#define   lson          l,m,rt<<1
#define   rson          m+1,r,rt<<1|1
#define   ll            long long
#define   ull           unsigned long long
#define   mem(n,v)      memset(n,v,sizeof(n))
#define   MAX           1000005
#define   MAXN          2000005
#define   PI            3.1415926
#define   E             2.718281828459
#define   opnin         freopen("text.in.txt","r",stdin)
#define   opnout        freopen("text.out.txt","w",stdout)
#define   clsin         fclose(stdin)
#define   clsout        fclose(stdout)

const int    INF    =   0x3f3f3f3f;
const ll     INFF   =   0x3f3f;
const double pi     =   3.141592653589793;
const double inf    =   1e18;
const double eps    =   1e-8;
const ll     mod    =   1e9+7;
const ull    mx     =   133333331;

ll p[MAX],cnt;//prime
void getprime(ll n)
{
    mem(p,0);
    cnt = 0;
    ll temp = sqrt(n);
    for(int i=2;i<=temp;i++){
        if(n % i == 0){
            p[cnt++] = i;
            while(n % i == 0) n /= i;
        }
        if(n < i) break;
    }
    if(n > 1) p[cnt++] = n;
}
ll a[MAX];
ll pix(ll n)
{
    mem(a,-1);
    ll t = 1,k,sum = 0;
    for(int i=0;i> kace;
    for(int i=1;i<=kace;i++){
        printf("Case #%d: ",i);
        solve();
    }

    return 0;
}


你可能感兴趣的:(ACM/ICPC)