Codeforces 922.F Divisibility
1 second
256 megabytes
standard input
standard output
Imp is really pleased that you helped him. But it you solve the last problem, his gladness would raise even more.
Let's define
for some set of integers
as the number of pairs a, b in
, such that:
- a is strictly less than b;
- a divides b without a remainder.
You are to find such a set , which is a subset of {1, 2, ..., n} (the set that contains all positive integers not greater than n), that
.
The only line contains two integers n and k .
If there is no answer, print "No".
Otherwise, in the first line print "Yes", in the second — an integer m that denotes the size of the set you have found, in the second line print m integers — the elements of the set
, in any order.
If there are multiple answers, print any of them.
3 3
No
6 6
Yes
5
1 2 4 5 6
8 3
Yes
4
2 4 5 8
In the second sample, the valid pairs in the output set are (1, 2), (1, 4), (1, 5), (1, 6), (2, 4), (2, 6). Thus, .
In the third example, the valid pairs in the output set are (2, 4), (4, 8), (2, 8). Thus, .
题目大意:在1~n中选任意个数组成一个集合I,定义f(I) = I中的每个数被I中的其它的多少个数整除的和.已知f(I) = k,求I.
分析:全程凭感觉做的一道题......
令d(i)表示i被1~i-1这些数整除的数的个数,e(i) = Σd(j) (1 ≤ j ≤ i).首先需要猜出一个结论:当e(n) ≥ k时,是肯定有解的. 更近一步,当e(i) ≥ k时,肯定有解,那么就可以把>i的数给丢掉.
假设e(pos) ≥ k,k变成e(pos) - k,将pos / 2 + 1到pos的d全都加入优先队列中,每次弹出最大的d,如果k≥d,则k -= d,并丢掉这个d对应的i.这是基本做法,为什么只需要pos / 2 + 1到pos的数就可以了呢?
如果考虑的数≤pos / 2,那么删掉这个数的贡献就不只是d,因为[pos / 2 + 1,pos]中有数是它的倍数,这个不好考虑.那为什么只考虑pos / 2 + 1到pos的数就一定最后能让k变成0呢?整除数m的数的个数是O(m ^ (1/3))的.而>m/2并且<m的质数的个数大约是个,一般后者的数量都比前者大,而质数的贡献是1,所以只删去质数就能满足要求,有极少数的数会出现后者比前者小,由于差的非常小,按照上述方法贪心地删就好了.
如果不按照d来考虑贡献,可以考虑只删除1~pos的质数,对于质数i,它的贡献是[pos / i],删除当前质数不影响其他质数的贡献,其实和上面的贪心方法差不多.
我曾经考虑过正向构造,每次考虑添加哪个数进去,但是贡献不好算,而且想不到什么好的策略. 这个方法就是把可能的数摆在你的面前,你要在里面删数,不仅要考虑能否满足要求,并且还要考虑贡献的计算问题. 挺考验数学直觉的.
#include <cstdio>
#include <queue>
#include <cstring>
#include <iostream>
#include <algorithm> using namespace std; int n,k,sum[],d[],cur,leftt,vis[],ans;
priority_queue <pair<int,int> >q; int main()
{
scanf("%d%d",&n,&k);
for (int i = ; i <= n; i++)
for (int j = i * ; j <= n; j += i)
d[j]++;
for (int i = ; i <= n; i++)
{
sum[i] = sum[i - ] + d[i];
if (sum[i] >= k)
{
leftt = sum[i] - k;
cur = i;
break;
}
}
if (!cur)
puts("No");
else
{
puts("Yes");
if (leftt == )
{
printf("%d\n",cur);
for (int i = ; i <= cur; i++)
printf("%d ",i);
}
else
{
for (int i = cur / + ; i <= cur; i++)
q.push(make_pair(d[i],i));
while (leftt)
{
pair <int,int> temp = q.top();
q.pop();
if (leftt >= temp.first)
{
leftt -= temp.first;
vis[temp.second] = ;
}
}
for (int i = ; i <= cur; i++)
if (!vis[i])
ans++;
printf("%d\n",ans);
for (int i = ; i <= cur; i++)
if (!vis[i])
printf("%d ",i);
}
} return ;
}
Codeforces 922.F Divisibility的更多相关文章
- Codeforces 959 F. Mahmoud and Ehab and yet another xor task
\(>Codeforces\space959 F. Mahmoud\ and\ Ehab\ and\ yet\ another\ xor\ task<\) 题目大意 : 给出一个长度为 \ ...
- Codeforces 835 F. Roads in the Kingdom
\(>Codeforces\space835 F. Roads in the Kingdom<\) 题目大意 : 给你一棵 \(n\) 个点构成的树基环树,你需要删掉一条环边,使其变成一颗 ...
- Codeforces 731 F. Video Cards(前缀和)
Codeforces 731 F. Video Cards 题目大意:给一组数,从中选一个数作lead,要求其他所有数减少为其倍数,再求和.问所求和的最大值. 思路:统计每个数字出现的个数,再做前缀和 ...
- Codeforces 797 F Mice and Holes
http://codeforces.com/problemset/problem/797/F F. Mice and Holes time limit per test 1.5 ...
- Codeforces 622 F. The Sum of the k-th Powers
\(>Codeforces \space 622\ F. The\ Sum\ of\ the\ k-th\ Powers<\) 题目大意 : 给出 \(n, k\),求 \(\sum_{i ...
- Codeforces 379 F. New Year Tree
\(>Codeforces \space 379 F. New Year Tree<\) 题目大意 : 有一棵有 \(4\) 个节点个树,有连边 \((1,2) (1,3) (1,4)\) ...
- Codeforces 538 F. A Heap of Heaps
\(>Codeforces \space 538 F. A Heap of Heaps<\) 题目大意 :给出 \(n\) 个点,编号为 \(1 - n\) ,每个点有点权,将这些点构建成 ...
- codeforces 825F F. String Compression dp+kmp找字符串的最小循环节
/** 题目:F. String Compression 链接:http://codeforces.com/problemset/problem/825/F 题意:压缩字符串后求最小长度. 思路: d ...
- [codeforces 618 F] Double Knapsack (抽屉原理)
题目链接:http://codeforces.com/contest/618/problem/F 题目: 题目大意: 有两个大小为 N 的可重集 A, B, 每个元素都在 1 到 N 之间. 分别找出 ...
随机推荐
- 网页弹出[Object HTMLDivElement],怎么取值?
使用innerHTML方法,可以得到文本值
- gzip,bzip2,xz压缩工具
gzip,bzip2,xz压缩工具====================== gzip压缩工具 示例:[root@aminglinux yasuo]# ls1.txt 2.txt 3.txt[roo ...
- asciinema使用
asciinema让您轻松记录终端会话,并在终端和网页浏览器中重播它们. 安装最新版本: sapt-get install asciinema 记录你的第一个终端视频: asciinema rec f ...
- ethereum(以太坊)(七)--枚举/映射/构造函数/修改器
pragma solidity ^0.4.10; //枚举类型 contract enumTest{ enum ActionChoices{Left,Right,Straight,Still} // ...
- js开发中常用小技巧
1.获取指定范围内的随机数 function getRadomNum(min,max){ return Math.floor(Math.random() * (max - min + 1)) + mi ...
- 千锋教育Vue组件--vue基础的方法
课程地址: https://ke.qq.com/course/251029#term_id=100295989 <!DOCTYPE html> <html> <head& ...
- openwrt(二) 配置openwrt及编译
导航 1. 配置openwrt 2. 编译openwrt 3. 错误记录 1. 配置openwrt 在openwrt的根目录下,执行make menuconfig. 这个界面我也只是了解了这两个选项而 ...
- POJ 3977 折半枚举
链接: http://poj.org/problem?id=3977 题意: 给你n个数,n最大35,让你从中选几个数,不能选0个,使它们和的绝对值最小,如果有一样的,取个数最小的 思路: 子集个数共 ...
- zeppelin的数据集的优化
前面我们介绍了zeppelin的修改,前面由于自己的原因,对zeppelin的修改过于多,现在由于优化了,我们两个类, 一个是zeppelin-server的NotebookServer的类的broa ...
- X的N次方。N比较大。
final static long DIV = 1000000009; //分治法, 注意java类型为long, C++为__int64或 long long public static long ...