hdu1695容斥原理

题意:已知给定k,x,y求 1<=a<=x 1<=b<=y 中满足 gcd(a,b)=k 的(a,b)对数。(注意数对是无序的)。 1<=x,y<=1e5, 0<=k<=1e5
区间中与i不互质的个数 = (区间中i的每个质因数的倍数个数)-(区间中i的每两个质因数乘积的倍数)+(区间中i的每3个质因数的乘积的倍数个数)-(区间中i的每4个质因数的乘积)+…

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() ;
           }

           out.flush() ; 


    }


}

class  Task{
       static int  N = 100000 ;
       static ArrayList<Integer>[] fac = new ArrayList[N+1] ;
       static boolean[] vis = new boolean[N+1] ;

       static{
             for(int i = 1 ; i <= N ; i++) fac[i] = new ArrayList<Integer>() ;

             for(int i = 2 ; i <= N ; i++){
                  if(! vis[i]){
                       for(int j = i ; j <= N ; j += i){
                            vis[j] = true ;
                            fac[j].add(i) ;
                       }
                  }
             }

       }

       int    gao(int h , int n){
              int sum = h  ;
              int m = fac[n].size() ;
              for(int i = 1 , limit = (1<<m) ; i < limit ; i++){
                     int k = 0 ;
                     int p = 1 ;
                     for(int j = 0 ; j < m ; j++){
                           if((i & (1<<j)) > 0){
                                k++ ;
                                p *= fac[n].get(j) ;
                           }
                     }
                     if((k&1) > 0) sum -= h/p ;
                     else sum += h/p ;
              }
              return sum ;
       }

       public void solve(InputReader in , PrintWriter out) throws IOException{
              in.nextInt() ;
              int L = in.nextInt() ;
              in.nextInt() ;
              int R = in.nextInt() ;
              int k = in.nextInt() ;
              if(k == 0){
                  out.println(0) ;
                  return ;
              }
              L /= k ;
              R /= k ;
              if(L > R){
                    L ^= R ; R ^= L ; L ^= R ;
              }

              long sum = 0 ;
              for(int i = 1 ; i <= R ; i++){
                   sum += gao(Math.min(i, L) , i) ;
              }

              out.println(sum) ;
       }


}

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());
        }

}

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