1. 程式人生 > >刷題總結——跳蚤(poj1091容斥+分解質因數)

刷題總結——跳蚤(poj1091容斥+分解質因數)

不同 個數 ·· sin push_back 10個 push back 居住

題目:

Description

Z城市居住著很多只跳蚤。在Z城市周六生活頻道有一個娛樂節目。一只跳蚤將被請上一個高空鋼絲的正中央。鋼絲很長,可以看作是無限長。節目主持人會給該跳蚤發一張卡片。卡片上寫有N+1個自然數。其中最後一個是M,而前N個數都不超過M,卡片上允許有相同的數字。跳蚤每次可以從卡片上任意選擇一個自然數S,然後向左,或向右跳S個單位長度。而他最終的任務是跳到距離他左邊一個單位長度的地方,並撿起位於那裏的禮物。
比如當N=2,M=18時,持有卡片(10, 15, 18)的跳蚤,就可以完成任務:他可以先向左跳10個單位長度,然後再連向左跳3次,每次15個單位長度,最後再向右連跳3次,每次18個單位長度。而持有卡片(12, 15, 18)的跳蚤,則怎麽也不可能跳到距他左邊一個單位長度的地方。
當確定N和M後,顯然一共有M^N張不同的卡片。現在的問題是,在這所有的卡片中,有多少張可以完成任務。

Input

兩個整數N和M(N <= 15 , M <= 100000000)。

Output

可以完成任務的卡片數。

Sample Input

2 4

Sample Output

12

Hint

這12張卡片分別是:
(1, 1, 4), (1, 2, 4), (1, 3, 4), (1, 4, 4), (2, 1, 4), (2, 3, 4),
(3, 1, 4), (3, 2, 4), (3, 3, 4), (3, 4, 4), (4, 1, 4), (4, 3, 4)

題解:

首先很明顯幾個數要滿足條件最大質因數要為1·····

然後就是分解質因數m,用容斥搞搞就出來了···

代碼:

#include<iostream>
#include
<cstdio> #include<cstdlib> #include<cmath> #include<ctime> #include<cctype> #include<cstring> #include<string> #include<algorithm> #include<vector> #define ul unsigned long long using namespace std; vector<int>zhiyinzi; ul ans=0,n,m; inline ul ksm(ul a,ul b) { ul temp
=1; while(b) { if(b%2==1) temp=temp*a; b=b/2; a=a*a; } return temp; } inline void dfs(int u,int tot,int f) { if(u==zhiyinzi.size()) { ul temp=m/tot; ans+=f*ksm(temp,n); return; } dfs(u+1,tot*zhiyinzi[u],-f); dfs(u+1,tot,f); } int main() { //freopen("a.in","r",stdin); cin>>n>>m; ul temp=m; for(int i=2;i*i<=temp;i++) { if(temp%i==0) { zhiyinzi.push_back(i); while(temp%i==0) temp/=i; } } if(temp!=1) zhiyinzi.push_back(temp); dfs(0,1,1); cout<<ans<<endl; return 0; }

刷題總結——跳蚤(poj1091容斥+分解質因數)