hdu 4135(容斥原理)


題意:就是讓你求(a,b)區間於n互質的數的個數.

分析:我們可以先轉化下:用(1,b)區間與n互質的數的個數減去(1,a-1)區間與n互質的數的個數,那么現在就轉化成求(1,m)區間於n互質的數的個數,如果要求的是(1,n)區間與n互質的數的個數的話,我們直接求出n的歐拉函數值即可,可是這里是行不通的!我們不妨換一種思路:就是求出(1,m)區間與n不互質的數的個數,假設為num,那么我們的答案就是:m-num!現在的關鍵就是:怎樣用一種最快的方法求出(1,m)區間與n不互質的數的個數?方法實現:我們先求出n的質因子(因為任何一個數都可以分解成若干個質數相乘的),如何盡快地求出n的質因子呢?我們這里又涉及兩個好的算法了!第一個:用於每次只能求出一個數的質因子,適用於題目中給的n的個數不是很多,但是n又特別大的;(http://www.cnblogs.com/jiangjing/archive/2013/06/03/3115399.html)第二個:一次求出1~n的所有數的質因子,適用於題目中給的n個數比較多的,但是n不是很大的。(http://www.cnblogs.com/jiangjing/archive/2013/06/01/3112035.html)本題適用第一個算法!舉一組實例吧:假設m=12,n=30.

第一步:求出n的質因子:2,3,5;

第二步:(1,m)中是n的因子的倍數當然就不互質了(2,4,6,8,10)->n/2  6個,(3,6,9,12)->n/3  4個,(5,10)->n/5  2個。

如果是粗心的同學就把它們全部加起來就是:6+4+2=12個了,那你就大錯特錯了,里面明顯出現了重復的,我們現在要處理的就是如何去掉那些重復的了!

第三步:這里就需要用到容斥原理了,公式就是:n/2+n/3+n/5-n/(2*3)-n/(2*5)-n/(3*5)+n/(2*3*5).

第四步:我們該如何實現呢?我在網上看到有幾種實現方法:dfs(深搜),隊列數組,位運算三種方法都可以!上述公式有一個特點:n除以奇數個數相乘的時候是加,n除以偶數個數相乘的時候是減。我這里就寫下用隊列數組如何實現吧:我們可以把第一個元素設為-1然后具體看代碼如何實現吧!

同種類型的題目:hdu 2841    hdu1695

代碼實現:

 

#include<iostream>
#include<string.h>
using namespace std;
__int64 a[1000],num;
void init(__int64 n)//求一個數的質因子
{
    __int64 i;
    num=0;
    for(i=2;i*i<=n;i++)
    {
        if(n%i==0)
        {
            a[num++]=i;
            while(n%i==0)
                n=n/i;
        }
    }
    if(n>1)//這里要記得
        a[num++]=n;
}
__int64 haha(__int64 m)//用隊列數組實現容斥原理
{
    __int64 que[10000],i,j,k,t=0,sum=0;
    que[t++]=-1;
    for(i=0;i<num;i++)
    {
        k=t;
        for(j=0;j<k;j++)
           que[t++]=que[j]*a[i]*(-1);
    }
    for(i=1;i<t;i++)
        sum=sum+m/que[i];
    return sum;
}
int main()
{
    __int64 T,x,y,n,i,sum;
    while(scanf("%I64d",&T)!=EOF)
    {
        for(i=1;i<=T;i++)
        {
           scanf("%I64d%I64d%I64d",&x,&y,&n);
           init(n);
           sum=y-haha(y)-(x-1-haha(x-1));
           printf("Case #%I64d: ",i);
           printf("%I64d\n",sum);
        }
    }
    return 0;
}

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM