2407:Relatives
keyword
約数 包除原理 C++
概要
n(<10^9)が与えられた時にn以下の互いに素な数がいくつあるか求める問題。
オイラーのφ関数使えば解けるけど包除原理使って普通に実装した。
int main(){ primeTable(100000); int n, i, j, ans, d, s, t; while(scanf("%d",&n)){ if(!n) break; ans = n-1; vector<int> fs; t = n; for(i=0;i<SZ(ps);i++)if(t%ps[i]==0){ fs.PB(ps[i]); while(t%ps[i]==0) t/=ps[i]; } if(t!=1) fs.PB(t); sort(ALL(fs)); fs.erase(unique(ALL(fs)), fs.end()); s = SZ(fs); vector<int> comb(s); REP(i,s){ REP(j,s){ if(j<=i) comb[j] = 1; else comb[j] = 0; } do{ d = 1; REP(j,s) d *= (comb[j])?fs[j]:1; d = (n-1)/d; ans -= (i%2)?-d:d; }while(prev_permutation(ALL(comb))); } printf("%d\n",ans); } return 0; }