题意:求第K个和M互质的数.
分析:求一个数和多少个数互质可以用容斥原理,二分一个数验证是不是第K个即可(16MS).
(另一种用欧拉函数的算法更快.)
code:
var p,c:array[0..10000] of longint; prime:array[0..100] of longint; v:array[0..1000001] of boolean; u:array[0..100] of boolean; m,n,k,i,nx,num:longint; l,r,mid,t:int64; procedure make(k,num:longint); var o:longint; begin if k>nx then exit; inc(n); p[n]:=num; c[n]:=k; v[num]:=true; for o:=1 to nx do if not u[o] then begin u[o]:=true; num:=num*prime[o]; if not v[num] then make(k+1,num); num:=num div prime[o]; u[o]:=false; end; end; function calc(num:int64):int64; var o:longint; tmp:int64=0; begin for o:=1 to n do if odd(c[o]) then tmp:=tmp-num div p[o] else tmp:=tmp+num div p[o]; exit(tmp); end; begin while not seekeof do begin readln(m,k); num:=m; nx:=0; for i:=2 to trunc(sqrt(m)) do if num mod i=0 then begin inc(nx); prime[nx]:=i; while num mod i=0 do num:=num div i; end; if num>1 then begin inc(nx); prime[nx]:=num; end; n:=0; fillchar(v,sizeof(v),0); make(0,1); l:=1; r:=1<<60; while l<r do begin mid:=(l+r)>>1; t:=calc(mid); if t>k then r:=mid-1 else if t<k then l:=mid+1 else r:=mid; end; writeln(l); end; end.