HDU 4135 Co-prime(容斥原理)
第一發容斥,感覺挺有意思的 →_→
【題目鏈接】Co-prime
【題目類型】容斥
&題意:
求(a,b)區間內,與n互質的數的個數。 \(a,b\leq 10^{15}\)
&題解:
分析:我們可以先轉化下:用(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然后具體看代碼如何實現吧!
【時間復雜度】O(\(\sqrt{n}\))
&代碼:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
#define cle(a,val) memset(a,(val),sizeof(a))
#define SI(N) scanf("%d",&(N))
#define SII(N,M) scanf("%d %d",&(N),&(M))
#define SIII(N,M,K) scanf("%d %d %d",&(N),&(M),&(K))
#define rep(i,b) for(int i=0;i<(b);i++)
#define rez(i,a,b) for(int i=(a);i<=(b);i++)
#define red(i,a,b) for(int i=(a);i>=(b);i--)
const ll LINF = 0x3f3f3f3f3f3f3f3f;
#define PU(x) puts(#x);
#define PI(A) cout<<(A)<<endl;
#define DG(x) cout<<#x<<"="<<(x)<<endl;
#define DGG(x,y) cout<<#x<<"="<<(x)<<" "<<#y<<"="<<(y)<<endl;
#define DGGG(x,y,z) cout<<#x<<"="<<(x)<<" "<<#y<<"="<<(y)<<" "<<#z<<"="<<(z)<<endl;
#define PIar(a,n) rep(i,n)cout<<a[i]<<" ";cout<<endl;
#define PIarr(a,n,m) rep(aa,n){rep(bb, m)cout<<a[aa][bb]<<" ";cout<<endl;}
const double EPS = 1e-9 ;
/* C o d i n g S p a c e */
const int MAXN = 10000 + 9 ;
ll a,b,n,phi[MAXN],num;
int K;
void pre(ll n){ll i;num=0;for(i=2;i*i<=n;i++){if (n%i==0){phi[num++]=i;while(n%i==0) n/=i;}}if (n>1) phi[num++]=n;
}
ll pie(ll m){ll que[MAXN],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]*phi[i]*(-1);}for(i=1;i<t;i++){sum+=m/que[i];}return sum;
}
void Solve()
{scanf("%lld%lld%lld",&a,&b,&n);pre(n);ll ans=b-pie(b)-(a-1-pie(a-1));printf("Case #%d: %lld\n",++K,ans);
}
int main()
{
#ifndef ONLINE_JUDGEfreopen("1.in", "r", stdin);freopen("1.out","w",stdout);
#endif
//iostream::sync_with_stdio(false);
//cin.tie(0), cout.tie(0);int T;cin>>T;while(T--)Solve();return 0;
} 轉載自: http://www.cnblogs.com/jiangjing/archive/2013/06/03/3115470.html
轉載于:https://www.cnblogs.com/s1124yy/p/5975554.html
總結
以上是生活随笔為你收集整理的HDU 4135 Co-prime(容斥原理)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 求一个关于四叶草的个性签名。
- 下一篇: 比较ArrayList、LinkedLi