P1978 集合

题目描述

集合是数学中的一个概念,用通俗的话来讲就是:一大堆数在一起就构成了集合。集合有如

下的特性:

•无序性:任一个集合中,每个元素的地位都是相同的,元素之间是无序的。

•互异性:一个集合中,任何两个元素都认为是不相同的,即每个元素只能出现一次。

•确定性:给定一个集合,任给一个元素,该元素或者属于或者不属于该集合,二者必居

其一,不允许有模棱两可的情况出现。

例如 A = {1, 2, 3} 就是一个集合。我们可以知道, 1 属于 A ,即 1 ∈ A ; 4 不属于 A ,

即 4 ∉ A 。一个集合的大小,就是其中元素的个数。

现在定义一个特殊的 k-集合,要求满足:

•集合的所有特性

•对任意一个该集合内的元素 x ,不存在一个数 y ,使得 y = kx 并且 y 属于该集合。即

集合中的任意一个数,它乘以 k 之后的数都不在这个集合内

给你一个由 n 个不同的数组成的集合,请你从这个集合中找出一个最大的 k-集合。

输入输出格式

输入格式:

第 1 行:两个整数: n 和 k

第 2 行:n 个整数: a[i] 表示给定的集合

输出格式:

第 1 行:一个整数: ans 表示最大的 k-集合的大小

输入输出样例

输入样例#1:

6 2
2 3 6 5 4 10
输出样例#1:

3

说明

提示:在样例所给集合中,找出的最大的 2-集合为 {4, 5, 6}

•对于 30% 的数据: n, k ≤ 100

•对于 40% 的数据: a[i] ≤ 231-1

•对于 70% 的数据: n, k ≤ 5000

•对于 100% 的数据: n, k ≤ 105, a[i] ≤ 263-1

Solution

tips:最近做题总是忘记longlong或者空间开小。。。郁闷

这道题可以排序后从大到小排序,对于每个数x,若k | x,二分找x / k,标记为不能选

由于是从大往小找,可知当前x是否选取影响不到比它大的数

其实从最小开始选也可以

证明:

对于奇数个连续的k的倍数(即 k * a, k * (a + 1), k * (a + 2)...)  可知从非最大(或最小)开始选一定不优于从最大开始选

对于偶数个连续的k的倍数(即 k * a, k * (a + 1),k * (a + 2),k * (a + 3).。。)   无论从哪一个开始选都等价

因此从最大(或最小)的开始选一定最优

但我们从最大开始,因为找的时候会做除法,不会爆long long范围

从最小开始需要做一些防止爆long long的处理

Code

从小开始找的代码:

#include <bits/stdc++.h>
inline void read(long long &x){x = 0;char ch = getchar();while(ch > '9' || ch < '0'){ch = getchar();}while(ch >= '0' && ch <= '9')x = x * 10 + ch - '0', ch = getchar();}
inline long long max(long long a, long long b){return a > b ? a : b;}
inline long long min(long long a, long long b){return a > b ? b : a;}
inline void swap(long long &a, long long &b){long long tmp = a;a = b;b = tmp;}
const long long INF = 0xfffffffffffffff; const int MAXN = 100000 + 10;
const int MAXK = 100000 + 10; long long num[MAXN],n,k;
bool b[MAXN];//记录哪一些数不能加入,true表示不能加 long long erfen(int l, int r, long long p)
{
long long mid;
while(l < r)
{
mid = l + ((r - l) >> 1);
if(num[mid] >= p)r = mid;
else l = mid + 1;
}
return l;
} long long ans; int main()
{
read(n);read(k);
for(int i = 1;i <= n;i ++)
{
read(num[i]);
}
std::sort(num + 1, num + 1 + n);
float ma = (float)num[n] / (float)k;
for(long long i = 1;i <= n;i ++)
{
if(!b[i])
{
ans ++;
if(num[i] > ma)continue;
long long tmp = erfen(i, n, num[i] * k);
if(num[tmp] == num[i] * k)
b[tmp] = true;
}
}
printf("%d", ans);
return 0;
}

从大开始找的代码:

#include <bits/stdc++.h>
inline void read(long long &x){x = 0;char ch = getchar();while(ch > '9' || ch < '0'){ch = getchar();}while(ch >= '0' && ch <= '9')x = x * 10 + ch - '0', ch = getchar();}
inline long long max(long long a, long long b){return a > b ? a : b;}
inline long long min(long long a, long long b){return a > b ? b : a;}
inline void swap(long long &a, long long &b){long long tmp = a;a = b;b = tmp;}
const long long INF = 0xfffffffffffffff; const int MAXN = 100000 + 10;
const int MAXK = 100000 + 10; long long num[MAXN],n,k;
bool b[MAXN];//记录哪一些数不能加入,true表示不能加 long long erfen(int l, int r, long long p)
{
long long mid;
while(l < r)
{
mid = l + ((r - l) >> 1);
if(num[mid] >= p)r = mid;
else l = mid + 1;
}
return l;
} long long ans; int main()
{
read(n);read(k);
for(int i = 1;i <= n;i ++)
{
read(num[i]);
}
std::sort(num + 1, num + 1 + n);
for(long long i = n;i >= 1;i --)
{
if(!b[i])
{
ans ++;
if(num[i] % k == 0)
{
long long tmp = erfen(1, i, num[i] / k);
if(num[tmp] * k == num[i])
b[tmp] = true;
}
}
}
printf("%d", ans);
return 0;
}

洛谷P1978 集合 [2017年6月计划 数论08]的更多相关文章

  1. 洛谷P1621 集合 [2017年6月计划 数论13]

    P1621 集合 题目描述 现在给你一些连续的整数,它们是从A到B的整数.一开始每个整数都属于各自的集合,然后你需要进行一下的操作: 每次选择两个属于不同集合的整数,如果这两个整数拥有大于等于P的公共 ...

  2. 洛谷P1062 数列 [2017年6月计划 数论03]

    P1062 数列 题目描述 给定一个正整数k(3≤k≤15),把所有k的方幂及所有有限个互不相等的k的方幂之和构成一个递增的序列,例如,当k=3时,这个序列是: 1,3,4,9,10,12,13,… ...

  3. 洛谷P2835 刻录光盘 [2017年6月计划 强连通分量02]

    P2835 刻录光盘 题目描述 在JSOI2005夏令营快要结束的时候,很多营员提出来要把整个夏令营期间的资料刻录成一张光盘给大家,以便大家回去后继续学习.组委会觉得这个主意不错!可是组委会一时没有足 ...

  4. 洛谷P2073 送花 [2017年6月计划 线段树01]

    P2073 送花 题目背景 小明准备给小红送一束花,以表达他对小红的爱意.他在花店看中了一些花,准备用它们包成花束. 题目描述 这些花都很漂亮,每朵花有一个美丽值W,价格为C. 小明一开始有一个空的花 ...

  5. 洛谷P1650 赛马[2017年5月计划 清北学堂51精英班Day1]

    P1650 赛马 题目描述 我国历史上有个著名的故事: 那是在2300年以前.齐国的大将军田忌喜欢赛马.他经常和齐王赛马.他和齐王都有三匹马:常规马,上级马,超级马.一共赛三局,每局的胜者可以从负者这 ...

  6. 洛谷P2258 子矩阵[2017年5月计划 清北学堂51精英班Day1]

    题目描述 给出如下定义: 子矩阵:从一个矩阵当中选取某些行和某些列交叉位置所组成的新矩阵(保持行与列的相对顺序)被称为原矩阵的一个子矩阵. 例如,下面左图中选取第2.4行和第2.4.5列交叉位置的元素 ...

  7. 洛谷P2196 挖地雷 [2017年4月计划 动态规划13]

    P2196 挖地雷 题目背景 NOIp1996提高组第三题 题目描述 在一个地图上有N个地窖(N<=20),每个地窖中埋有一定数量的地雷.同时,给出地窖之间的连接路径.当地窖及其连接的数据给出之 ...

  8. 洛谷P2723 丑数 Humble Numbers [2017年 6月计划 数论07]

    P2723 丑数 Humble Numbers 题目背景 对于一给定的素数集合 S = {p1, p2, ..., pK},考虑一个正整数集合,该集合中任一元素的质因数全部属于S.这个正整数集合包括, ...

  9. 洛谷P1368 均分纸牌(加强版) [2017年6月计划 数论14]

    P1368 均分纸牌(加强版) 题目描述 有 N 堆纸牌,编号分别为 1,2,…, N.每堆上有若干张,纸牌总数必为 N 的倍数.可以在任一堆上取1张纸牌,然后移动. 移牌规则为:在编号为 1 堆上取 ...

随机推荐

  1. 点击回退时需要点击2次才可返回js

    为a加上window.location.href跳转页面时,再返回到此页面,再点击返回时需点击2次才能返回到前一个页面,原因竟然是href=“#”的原因,在html中#可做为锚点 http://blo ...

  2. 简单科普下hosts文件原理与制作

    简单科普下hosts文件原理与制作 hosts文件是一个用于储存计算机网络中各节点信息的计算机文件.这个文件负责将主机名映射到相应的IP地址.hosts文件通常用于补充或取代网络中DNS的功能.和DN ...

  3. Android基础控件ScrollView滚动条的使用

    1.简介 ScrollView是一个FrameLayout的容器,不过在他的基础上添加了滚动,允许显示的比实际多的内容!另外,只能够往里面放置一个子元素,可以是单一的组件,又或者一个布局包裹着的复杂的 ...

  4. 一个四五年的Java开发程序员,该准备哪些去面试?

    上周面试了一周,感触颇深,总结一下. 面试了公司大概有阿里,携程,爱奇艺,唯品会,途牛,bilibili,大众点评,阿里和爱奇艺是电话面试,其他现场面试. 首先,五年左右,应该算高级开发工程师,大部分 ...

  5. Spring容器管理各种文件

    1. 导入文件 <import resource="applicationContext-dataSource.xml" /> 2. 引用资源配置文件 <cont ...

  6. 动态规划——DP算法(Dynamic Programing)

    一.斐波那契数列(递归VS动态规划) 1.斐波那契数列——递归实现(python语言)——自顶向下 递归调用是非常耗费内存的,程序虽然简洁可是算法复杂度为O(2^n),当n很大时,程序运行很慢,甚至内 ...

  7. leetcode 49 Group Anagram

    lc49 Group Anagram 逻辑很简单,就是统计字母出现次数,然后将完全相同的字符串放入同一list 关键是怎么实现 统计的部分,可以通过将string排序,Arrays.sort(),或者 ...

  8. PostgreSQL 优化器代码概览

    简介 PostgreSQL 的开发源自上世纪80年代,它最初是 Michael Stonebraker 等人在美国国防部支持下创建的POSTGRE项目.上世纪末,Andrew Yu 等人在它上面搭建了 ...

  9. vim 插入行号

    :let i=1000000|g/^/s//\=i.' '/|let i=i+1

  10. javascript的Touch事件

    js的touch事件,一般用于移动端的触屏滑动 $(function(){document.addEventListener("touchmove", _touch, false) ...