hdu1796容斥原理

来源:互联网 发布:网络衣服 编辑:程序博客网 时间:2024/04/29 15:57

题目大意:给定n和一个大小为m的集合,集合元素为非负整数。为1…n内能被集合里任意一个数整除的数字个数。n<=2^31,m<=10

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) ;           while(cin.nextToken() != cin.TT_EOF){                long n = (long) cin.nval ;                 n-- ;                cin.nextToken() ; int  m = (int) cin.nval ;                new Task().solve(n , m , cin, out);            }           out.flush() ;     }}class  Task{       long gcd(long x , long y){            return y == 0 ? x : gcd(y , x % y) ;       }       long lcm(long x , long y){            return x / gcd(x , y) * y ;       }       public void solve(long n , int m ,StreamTokenizer cin , PrintWriter out) throws IOException{              ArrayList<Long> num = new ArrayList<Long>()  ;              for(int i = 0 ; i < m ; i++){                  cin.nextToken(); long c = (long)cin.nval ;                  if(c != 0) num.add(c) ;              }              m = num.size() ;              int limit = 1<<m ;              long sum = 0 ;              for(int i = 1 ; i < limit ; i++){                   int k = 0 ;                   long val = 1 ;                   for(int j = 0 ; j < m ; j++){                        if((i & (1<<j)) > 0){                             k++ ;                             val = lcm(val , num.get(j)) ;                        }                             }                   if((k&1) > 0) sum += n / val ;                   else sum -= n / val ;              }              out.println(sum);// out.flush();        }}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());        }}
0 0