I and OI
Past...

题意:求第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.
posted on 2011-08-13 13:48  exponent  阅读(731)  评论(0编辑  收藏  举报