hdu3388容斥原理

题意:给三个数m,n,k,求与m,n同时互质的第k个正整数(按从小到达顺序排列).

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.NavigableSet;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.Scanner;
import java.util.Set;
import java.util.SortedSet;
import java.util.Stack;
import java.util.StringTokenizer;
import java.util.TreeSet;

public class Main {

    public static void main(String[] args) throws IOException{
           StreamTokenizer cin = new StreamTokenizer(new BufferedInputStream(System.in)); 
           InputReader in = new InputReader(System.in)  ;
           PrintWriter out = new PrintWriter(System.out) ;
           int t = in.nextInt() ;
           for(int i = 1 ; i <= t ; i++){
                out.print("Case " + i + ": ");
                new Task().solve(in, out); 
           }

           out.flush() ; 


    }


}

class  Task{
       static int  N = 32000 ;
       static int[] prime = new int[N+1] ;
       static int pid = 0 ;
       static boolean[] vis = new boolean[N+1] ;
       static{
             for(int i = 2 ; i <= N ; i++){
                 if(! vis[i]) prime[pid++] = i ;
                 for(int j = 0 ; j < pid && i*prime[j] <= N ; j++){
                      vis[prime[j]*i] = true ;
                      if(i % prime[j] == 0) break ;
                 }
             }

       }

       ArrayList<Integer> fac = new ArrayList<Integer>() ;
       void  factor(int n){
             for(int i = 0 ; i < pid && prime[i] * prime[i] <= n ; i++){
                   if(n % prime[i] == 0){
                        while(n % prime[i] == 0) n /= prime[i] ;
                        fac.add(prime[i]) ;
                   }
             } 
             if(n != 1) fac.add(n) ;
       }
       ArrayList<Integer> adj = new ArrayList<Integer>() ;

       long  sum(long n){
             long s = n ;
             int m = adj.size() ;
             int limit = 1<<m ;
             for(int i = 1 ; i < limit ; i++){
                 long val = 1 ;
                 int k = 0 ; 
                 for(int j = 0 ; j < m ; j++){
                      if((i & (1<<j)) > 0){
                           k++ ;
                           val *= adj.get(j) ;
                      }
                 }
                 if((k & 1) > 0) s -= n/val ;
                 else s += n/val ;
             }
             return s ;
       }


       public void solve(InputReader in , PrintWriter out) throws IOException{
              int m = in.nextInt() ;
              int n = in.nextInt() ;
              long k = in.nextInt() ;
              factor(n) ;
              factor(m) ;

              Collections.sort(fac);

              adj.add(fac.get(0)) ;
              for(int i = 1 ; i < fac.size() ; i++){
                    if(fac.get(i) != fac.get(i-1)) adj.add(fac.get(i)) ;
              }

              long l = 1 , r = Long.MAX_VALUE , mid , s = -1 ;
              while(l <= r){
                    mid = (l + r) >> 1 ;
                    if(sum(mid) >= k){
                         s = mid ;
                         r = mid - 1 ; 
                    }
                    else l = mid + 1 ;
              }
              out.println(s) ;

       }

}

class   InputReader{
        public BufferedReader  reader;
        public StringTokenizer  tokenizer;

        public InputReader(InputStream stream){
                    reader = new BufferedReader(new InputStreamReader(stream), 32768) ;
                    tokenizer = null ;
        }

        public String next(){
                    while(tokenizer == null || ! tokenizer.hasMoreTokens()){
                        try{
                                tokenizer = new StringTokenizer(reader.readLine());
                        }catch (IOException e) {
                                throw new RuntimeException(e);
                        }
                    }
                    return tokenizer.nextToken();  
        }

        public int  nextInt(){
                    return Integer.parseInt(next());
        }

        public long nextLong(){
                    return Long.parseLong(next());
        }

        public double nextDouble(){
                    return  Double.parseDouble(next());
        }

}

你可能感兴趣的:(hdu3388容斥原理)