zoukankan      html  css  js  c++  java
  • Codeforces 922F Divisibility (构造 + 数论)

    题目链接  Divisibility

    题意 给定$n$和$k$,构造一个集合$left{1, 2, 3, ..., n ight}$的子集,使得在这个集合中恰好有$k$对正整数$(x, y)$, $x < y$

       满足$x$是$y$的约数。

     

    选定$1$和$2$,

    首先把满足 $x > [frac{n}{2}] $的质数$x$留出来,

    然后把满足 $ [frac{n}{3}]  < x <=  [frac{n}{2}] $的质数,以及他们的两倍留出来,
     
    留出来的这些数先不选,从$3$开始一个个开始选。
     
    接近$k$的时候开始选刚刚留出来的那些数,
     
    先选满足 $x > [frac{n}{2}] $的质数,满足题意的正整数对数加$1$,
     
    再选满足 $ [frac{n}{3}]  < x <=  [frac{n}{2}] $的质数的两倍,满足题意的正整数对数加$2$,
     
    最后选满足 $ [frac{n}{3}]  < x <=  [frac{n}{2}] $的质数,满足题意的正整数对数加$2$。
     
    选完这些如果还是到不了$k$,那么无解。
     
    本来想着$n$小的时候直接特判($O(2^{n})$暴力,但是把特判去掉交上去居然也通过了……
     
    #include <bits/stdc++.h>
    
    using namespace std;
    
    #define rep(i, a, b)	for (int i(a); i <= (b); ++i)
    #define dec(i, a, b)	for (int i(a); i >= (b); --i)
    
    const int N = 3e5 + 10;
    
    int a[N], b[N], c[N], f[N];
    int n, k, num1 = 0, num2 = 0;
    vector <int> c1, c21, c22;
    vector <int> ans;
    
    void print(){
    	puts("Yes");
    	sort(ans.begin(), ans.end());
    	int sz = ans.size();
    
    	printf("%d
    ", sz);
    	int fg = 0;
    	for (auto u : ans){
    		if (!fg) fg = 1;
    		else putchar(32);
    		printf("%d", u);
    	}
    
    	putchar(10);
    	exit(0);
    }
    
    
    void calc(){
    	int x1 = c1.size(), x21 = c21.size(), x22 = c22.size();
    	if (k & 1){
    		if (num1 == 0){ puts("No"); exit(0);}
    
    		while (k >= 3 && x22 > 0){
    			k -= 2;
    			--x22;
    			ans.push_back(c22[x22]);
    			c22.pop_back();
    		}
    
    		while (k >= 3 && x21 > 0){
    			k -= 2;
    			--x21;
    			ans.push_back(c21[x21]);
    			c21.pop_back();
    		}
    
    		while (k > 0 && x1 > 0){
    			k--;
    			--x1;
    			ans.push_back(c1[x1]);
    			c1.pop_back();
    		}
    
    		if (k > 0){ puts("No"); exit(0); }
    		print();
    	}
    
    	else{
    		while (k >= 2 && x22 > 0){
    			k -= 2;
    			--x22;
    			ans.push_back(c22[x22]);
    			c22.pop_back();
    		}
    
    		while (k >= 2 && x21 > 0){
    			k -= 2;
    			--x21;
    			ans.push_back(c21[x21]);
    			c21.pop_back();
    		}
    
    		while (k > 0 && x1 > 0){
    			k--;
    			--x1;
    			ans.push_back(c1[x1]);
    			c1.pop_back();
    		}
    
    		if (k > 0){ puts("No"); exit(0);}
    		print();
    	}
    }
    
    int main(){
    
    	scanf("%d%d", &n, &k);
    
    
    	rep(i, 2, 3e5 + 1){
    		if (!b[i]){
    			for (int j = i + i; j <= 3e5 + 1; j += i)
    				b[j] = 1;
    		}
    	}
    
    	rep(i, 1, 3e5 + 1){
    		for (int j = i; j <= 3e5 + 1; j += i) ++f[j];
    		--f[i];
    	}
    
    	c[1] = 1, c[2] = 1;
    	rep(i, n / 2 + 1, n) if (!b[i]){
    		if (i <= 2) continue;
    		c[i] = 1;
    		c1.push_back(i);
    		++num1;
    	}
    
    	rep(i, n / 3 + 1, n / 2) if (!b[i]){
    		if (i <= 2) continue;
    		c[i] = 1;
    		c[i << 1] = 1;
    		c21.push_back(i);
    		c22.push_back(i * 2);
    		++num2;
    	}
    
    	--k;
    	ans.push_back(1);
    	ans.push_back(2);
    	if (k == 0) print();
    
    	rep(i, 3, n){
    		if (c[i]) continue;
    		if (k >= f[i]){
    			k -= f[i];
    			ans.push_back(i);
    		}
    		else calc();	
    	}
    	
    	calc();	
    	return 0;
    }
    

      

     
  • 相关阅读:
    js模版引擎handlebars.js实用教程——由于if功力不足引出的Helper
    js模版引擎handlebars.js实用教程——if-判断的基本用法
    js模版引擎handlebars.js实用教程——with-终极this应用
    js模版引擎handlebars.js实用教程——with-进入到某个属性(进入到某个上下文环境)
    js模版引擎handlebars.js实用教程——each-循环中使用this
    mysql 索引及查询优化总结
    面试篇——mysql
    设计模式六大原则(5):迪米特法则
    BigInteger与BigDecimal
    Java基本类型占用字节数(或 bit数)
  • 原文地址:https://www.cnblogs.com/cxhscst2/p/8437907.html
Copyright © 2011-2022 走看看