E. Pencils and Boxes
time limit per test

2 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

Mishka received a gift of multicolored pencils for his birthday! Unfortunately he lives in a monochrome world, where everything is of the same color and only saturation differs. This pack can be represented as a sequence a1, a2, ..., an of n integer numbers — saturation of the color of each pencil. Now Mishka wants to put all the mess in the pack in order. He has an infinite number of empty boxes to do this. He would like to fill some boxes in such a way that:

  • Each pencil belongs to exactly one box;
  • Each non-empty box has at least k pencils in it;
  • If pencils i and j belong to the same box, then |ai - aj| ≤ d, where |x| means absolute value of x. Note that the opposite is optional, there can be pencils i and j such that |ai - aj| ≤ d and they belong to different boxes.

Help Mishka to determine if it's possible to distribute all the pencils into boxes. Print "YES" if there exists such a distribution. Otherwise print "NO".

Input

The first line contains three integer numbers n, k and d (1 ≤ k ≤ n ≤ 5·105, 0 ≤ d ≤ 109) — the number of pencils, minimal size of any non-empty box and maximal difference in saturation between any pair of pencils in the same box, respectively.

The second line contains n integer numbers a1, a2, ..., an (1 ≤ ai ≤ 109) — saturation of color of each pencil.

Output

Print "YES" if it's possible to distribute all the pencils into boxes and satisfy all the conditions. Otherwise print "NO".

Examples
Input
6 3 10
7 2 7 7 4 2
Output
YES
Input
6 2 3
4 5 3 13 4 10
Output
YES
Input
3 2 5
10 16 22
Output
NO
Note

In the first example it is possible to distribute pencils into 2 boxes with 3 pencils in each with any distribution. And you also can put all the pencils into the same box, difference of any pair in it won't exceed 10.

In the second example you can split pencils of saturations [4, 5, 3, 4] into 2 boxes of size 2 and put the remaining ones into another box.

【题意】

给$$$n$$$个数,可以放到若干个盒子里,要求每个盒子至少有$$$k$$$个数,并且每个盒子中最大和最小的数差值不超过$$$d$$$。问是否有合理的方案来分配。

【分析】

因为要比较差值,所以按从小到大对输入排序,如果$$$a_i$$$和$$$a_j$$$已经放到同一个盒子里了,那么大小介于$$$a_i$$$和$$$a_j$$$之间的数也一定可以放到这个盒子中。

由于上述的性质,每个盒子都应该装$$$a_i$$$~$$$a_j$$$的全部数。因为$$$a_i$$$和$$$a_j$$$是离其他数最近的数,如果现在的分配不可行,一定是先把$$$a_i$$$或$$$a_j$$$重新划分给相邻的盒子,成为新的区间端点,而整个方案依然的连续的;而如果$$$a_i$$$和$$$a_j$$$不能分配给其他盒子,那么内部的其他数也一定不行。从另一方面来说,如果把一个$$$a_i$$$~$$$a_j$$$中的一个$$$a_x$$$拿出去,最终形成了可行方案,那么一定可以通过把$$$a_x$$$与$$$a_i$$$或$$$a_j$$$交换,使方案依然可行而且每个盒子中变成连续的区间。

连续分配说明完了,之后都把盒子当作区间来处理,问题转化为:把1~n个数分为几个连续的区间,使的每个区间$$$[a_i, a_j]$$$的$$$a_j-a_i \le d, j-i \ge k$$$。

预处理:对于每个$$$a_i$$$一定有一个最大的$$$a_j$$$,用二分查找得到其下标,并把$$$a_j$$$下一个位置也就是$$$j+1$$$记录到$$$right[i]$$$ (下面会介绍) 中。

如果一个盒子是$$$[a_i, a_j]$$$那么下一个盒子的起点就是$$$a_{j+1}$$$。可以把从$$$a_i$$$到$$$a_{j+1}$$$看成一次转移,这样重复下去,如果最后刚好能到达数列的末端,那么从$$$a_i$$$开始就是可行的,$$$a_i$$$就是能到末端的点。这个时候$$$right[i]$$$数组就发挥作用了,对于$$$a_i$$$,它能转移到的起点有 $$$a_{i+k}, a_{i+k+1}, ...,a_{right[i]}$$$;

dp可以采取从后向前的顺序。在考虑$$$a_i$$$作为起点时,它可以转移到的点都在它后面,所以$$$[a_{i+k}, a_{right[i]}]$$$都处理过了,只要其中包含末端,或者能到末端的点,那么$$$a_i$$$也是能到达末端的点;如果区间不存在,或者不包含能到末端的点,那么$$$a_i$$$就不能到达末端。这样从后向前处理完所有点以后,起点能否到达末端就是答案的YES/NO。

如果用0表示无法到达末端,1表示能到达末端,那么转移方程就是:

$$$$$$dp[i]= (\sum_{j=i+k}^{right[i]} dp[j]) \gt 0$$$$$$

起始状态为$$$dp[n]$$$=$$$1$$$。

【注意】

使用树状数组来完成求和操作,下标的起点必须是1。

#include<stdio.h>
#include<algorithm>
using std::sort; #define N_max 500005
int ipt[N_max], right[N_max]; int n, k, d;
int cmpv(int t1, int t2) {
return t1 < t2;
}
void cal_r(int i) {
if (right[i] != 0)return;
int l = i, r = n + 1, m;
while (l + 1<r)
{
m = (l + r) / 2;
if (ipt[m] <= ipt[i] + d)l = m;
else r = m;
}
right[i] = r;
}
struct BIT {
int c[N_max] = { 0 };//每个ci维护的都是1~i的最新和
int lowbit[N_max] = { 0 };
int n;
BIT(int _n = N_max) {
n = _n;
for (int i = 1; i <= N_max; ++i) lowbit[i] = (i&(-i));
}
void newBIT(int _n) {
n = _n;
for (int i = 1; i <= n; ++i)
c[i] = 0;
}
//更新时向右(上)更新
void update(int x, int num) {
while (x <= n) {
c[x] += num;
x += lowbit[x];
}
}
//求和时向左(下)依次求和
int getsum(int x) {
int s = 0;
while (x > 0) {
s += c[x];
x -= lowbit[x];
}
return s;
}
}bit;
int main() {
scanf("%d %d %d", &n, &k, &d);
bit.newBIT(n+1);
for (int i = 1; i <= n; ++i)
scanf("%d", ipt + i); sort(ipt + 1, ipt + n + 1, cmpv);
int state;
//初始状态为只有末端可以到达末端
bit.update(n + 1, 1);
//计算right[i]
for (int i = 1; i <= n; ++i)
cal_r(i);
//从后向前dp
for (int i = n; i >= 1; --i)
{
if (i + k - 1 <= n)//至少存在一个
{
//使用树状数组判断区间内是否有不为0 的值
state = (bit.getsum(right[i]) - bit.getsum(i + k - 1)) > 0;
bit.update(i, state);
}
}
state = bit.getsum(1);
printf("%s", state == 1 ? "YES" : "NO");
return 0;
}

codeforces 985 E. Pencils and Boxes (dp 树状数组)的更多相关文章

  1. 树形DP+树状数组 HDU 5877 Weak Pair

    //树形DP+树状数组 HDU 5877 Weak Pair // 思路:用树状数组每次加k/a[i],每个节点ans+=Sum(a[i]) 表示每次加大于等于a[i]的值 // 这道题要离散化 #i ...

  2. bzoj 1264 [AHOI2006]基因匹配Match(DP+树状数组)

    1264: [AHOI2006]基因匹配Match Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 793  Solved: 503[Submit][S ...

  3. 【bzoj2274】[Usaco2011 Feb]Generic Cow Protests dp+树状数组

    题目描述 Farmer John's N (1 <= N <= 100,000) cows are lined up in a row andnumbered 1..N. The cows ...

  4. 奶牛抗议 DP 树状数组

    奶牛抗议 DP 树状数组 USACO的题太猛了 容易想到\(DP\),设\(f[i]\)表示为在第\(i\)位时方案数,转移方程: \[ f[i]=\sum f[j]\;(j< i,sum[i] ...

  5. CodeForces - 597C Subsequences 【DP + 树状数组】

    题目链接 http://codeforces.com/problemset/problem/597/C 题意 给出一个n 一个 k 求 n 个数中 长度为k的上升子序列 有多少个 思路 刚开始就是想用 ...

  6. codeforces 597C C. Subsequences(dp+树状数组)

    题目链接: C. Subsequences time limit per test 1 second memory limit per test 256 megabytes input standar ...

  7. Codeforces 1096F(dp + 树状数组)

    题目链接 题意: 对于长度为$n$的排列,在已知一些位的前提下求逆序对的期望 思路: 将答案分为$3$部分 $1.$$-1$与$-1$之间对答案的贡献.由于逆序对考虑的是数字之间的大小关系,故假设$- ...

  8. Codeforces 909 C. Python Indentation (DP+树状数组优化)

    题目链接:Python Indentation 题意: Python是没有大括号来标明语句块的,而是用严格的缩进来体现.现在有一种简化版的Python,只有两种语句: (1)'s'语句:Simple ...

  9. Codeforces 1085G(1086E) Beautiful Matrix $dp$+树状数组

    题意 定义一个\(n*n\)的矩阵是\(beautiful\)的,需要满足以下三个条件: 1.每一行是一个排列. 2.上下相邻的两个元素的值不同. 再定义两个矩阵的字典序大的矩阵大(从左往右从上到下一 ...

随机推荐

  1. 北京Uber优步司机奖励政策(11月16日~11月22日)

    用户组:人民优步“关羽组”(适用于11月16日-11月22日)奖励政策: 滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/ ...

  2. CC3200-LAUNCHXL仿真器驱动异常(未完成)

    1. 测试中发现,跳线帽J2和J3连接的情况下,驱动不正常如图2,不连接的情况下,驱动正常,VCC_LDO_3V3给仿真器FT2232供电,VCC_BRD这个电源很奇怪,用途不清晰,VBAT_CC是给 ...

  3. YUM本地源制作与yum网络版仓库

    1.修改本机上的YUM源配置文件,将源指向自己 cd /etc/yum.repos.d/ 备份原有的YUM源的配置文件 rename .repo .repo.bak * rename CentOS-M ...

  4. SQL学习(时间,存储过程,触发器)

    SQL学习 几个操作时间的函数 --datapart 获取时间中的年月日时分秒等部分 select DATEPART(year,current_timestamp); select DATEPART( ...

  5. Java开发工程师(Web方向) - 02.Servlet技术 - 第1章.Servlet

    第1章--Servlet Servlet简介 Servlet应用于? 浏览器发出HTTP请求,服务器接收请求后返回响应给浏览器. 接收请求后到返回响应之间: 服务器将请求对象转交给Servlet容器 ...

  6. 微服务框架Dubbo与Springcloud的区别

    微服务框架Dubbo与Springcloud的区别 微服务主要的优势如下: 1.降低复杂度 将原来偶合在一起的复杂业务拆分为单个服务,规避了原本复杂度无止境的积累.每一个微服务专注于单一功能,并通过定 ...

  7. Microsoft Edge 浏览器开始支持webkit私有样式

    微软表示新版的浏览器Edge(spartan)不会再增加新的私有属性,同时移除了部分-ms-属性,但很多标准在没有支持到之前,会使用webkit的api.Edge开发工程师Jacob Rossi列出了 ...

  8. Multi-task Correlation Particle Filter for Robust Object Tracking--论文随笔

    摘要:在这篇论文中,作者提出一种鲁棒视觉跟踪的多任务相关粒子滤波琪跟踪算法(MCPF).作者首先向我们展示了多任务相关滤波器,该滤波器在训练滤波器模板的时候可以学习不同特征之间的联系.本文提出的MCP ...

  9. AttributeError: 'TimeLimit' object has no attribute 'monitor'

    原报错代码部分: env.monitor.start(monitor_path, resume=True, video_callable=lambda count: count % record_vi ...

  10. Python3 标准库:calendar,time

    1.calendar import calendar print(calendar.month(2008,8)) #某个月 print(calendar.calendar(2008)) #某年 pri ...