[codeforces920G] 容斥+二分

題意:求出與p互質並且大於x的第k個數

思路:首先我們可以求出p的所有質因子,可以根據a/b表示[1,a]中以b爲因子的數的個數,然後用這個通過容斥來求得[1,a]中與與p互質的數的個數,然後就可以愉快地二分了。

import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.StreamTokenizer;
import java.math.BigInteger;
import java.util.ArrayList;
import java.io.BufferedReader;
import java.io.InputStreamReader;



public class Main {
    public static void main(String[] args) throws IOException {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader sc = new InputReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        Task solver = new Task();
        solver.solve(1, sc, out);
        out.close();
    }

    static class Task {
    	public int getCnt(int x,ArrayList<Integer> factor) {    //二進制枚舉容斥
    		int ans=x;
    		
    		for(int i=1;i<(1<<(factor.size()));i++) {
    			int cnt=0;
    			int temp=1;
    			for(int j=0;j<factor.size();j++) {
    				if((i&(1<<j))!=0) {
    					temp*=factor.get(j);
    					cnt++;
    				}
    			}
    			if(cnt%2==1)               //注意符號
    				ans-=x/temp;
    			else
    				ans+=x/temp;
    		}
    		
    		return ans;
    	}
    	
    	public boolean check(int x,int k,int preCnt,ArrayList<Integer> factor) {
    		return getCnt(x,factor)-preCnt>=k;
    	}
    	
        public void solve(int testNumber, InputReader sc, PrintWriter out) throws IOException {
        	ArrayList<Integer> factor=new ArrayList<Integer>();
        	int T=sc.nextInt();
        	
        	while(T-->0) {
        		factor.clear();
        		int x=sc.nextInt();
        		int p=sc.nextInt();
        		int k=sc.nextInt();
        		
        		
        		for(int i=2;i*i<=p;i++) {
        			if(p%i==0)
        				factor.add(i);
        			while(p%i==0)
        				p/=i;
        		}
        		if(p!=1)
        			factor.add(p);
        		
        		int preCnt=getCnt(x,factor);
        		int l=x+1;
        		int r=(int) 1e7;
        		int ans=-1;
        		while(l<=r) {
        			int mid=(l+r)>>1;
        		    if(check(mid,k,preCnt,factor)) {
        		    	r=mid-1;
        		    	ans=mid;
        		    }
        		    else
        		    	l=mid+1;
        		}
        		out.println(ans);
        	}
        }
    }

    static class InputReader{
        StreamTokenizer tokenizer;
        public InputReader(InputStream stream){
            tokenizer=new StreamTokenizer(new BufferedReader(new InputStreamReader(stream)));
            tokenizer.ordinaryChars(33,126);
            tokenizer.wordChars(33,126);
        }
        public String next() throws IOException {
            tokenizer.nextToken();
            return tokenizer.sval;
        }
        public int nextInt() throws IOException {
            return Integer.parseInt(next());
        }
        public long nextLong() throws IOException {
            return Long.parseLong(next());
        }
        public boolean hasNext() throws IOException {
            int res=tokenizer.nextToken();
            tokenizer.pushBack();
            return res!=tokenizer.TT_EOF;
        }
        
        public double nextDouble() throws NumberFormatException, IOException {
        	return Double.parseDouble(next());
        }
        
        public BigInteger nextBigInteger() throws IOException {
        	return new BigInteger(next());
        }
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章