题解:CF1468H K and Medians
题意简析
给定两个序列 \(a,b\) , \(b\) 是给定的单调不减的序列。
现在你可以若干次操作,每次操作选择序列 \(a\) 的 \(k\) 个整数,然后删除这 \(k\) 个数里除了他们的中位数的其他 \(k-1\) 个数。问你能否通过若干次操作,得到序列 \(b\) 。
分析
因为每次操作之后,我们都会去掉 \(k-1\) 个数,那么如果有解则有
其中 \(n\) 是 \(a\) 的长度, \(m\) 是 \(b\) 的长度。如果不满足,则输出 “NO”。
现在考虑如何判断有解
举个栗子: 第二个样例 \(n=7\),\(m=3\), \(k=3\), \(b_i={1, 5, 7}\) 。我们发现需要把 \(5\) 前面的 \(2, 3, 4\) ,和后面的 \(6\) 给删掉。
再举个梨子: 第四个样例 \(n=13\) ,\(m=7\) ,\(k=7\) ,\(b_i={1,3,5,7,9,11,12}\) 。发现 \(7\) 前面需删 \(2,4,6\) 三个数,后面需删 \(8,10,13\) 三个数。这两种情况都是有解的。
我们猜测,如果有一个数满足:需要删的数中,小于它的数的个数,和大于它的数的个数均大于 \(\frac{k-1}{2}\) ,那么一定有解。
下面是证明。
设 \(d=\frac{k-1}{2}\) ,假设我们找到一个数 \(p\) , 其中比它小的需要删除的数的个数记作 \(x\) , 比它大的需要删除的数的个数记作 \(y\) 。所以 \(x+y=n-m\equiv0\pmod{k-1}\) 。记 \(x'=x-d\) , \(y'=y-d\) , (前后各去掉 \(d\) 个数)所以有
因此
于是我们一定能找到至少一种方法把这 \(x'+y'\) 个数全部删掉(最后一次,可以去序列中借一个数来当中位数)。那么只剩下 \(d+1+d=k\) 个数,我们需要留下的数 \(p\) 正好就是这 \(k\) 个数的中位数。因为,正好有 \(d\) 个数小于它,正好有 \(d\) 个数大于它。最后我们把 \(k-1\) 个数删去就得到了我们想要的序列。
总结
无解的情况只需判断是否满足
否则,我们统计每个需要保留的数前后,各需要删除几个数,如果有一个数满足需要删除的数中小于它的数的个数,和大于它的数的个数均大于 \(\frac{k-1}{2}\) ,那么一定有解。
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 5;
inline int read(){
int x = 0, f = 1; char c = getchar();
while (! isdigit(c)) {
if (c == '-') f = -1;
c = getchar();
}
while(isdigit(c)) {
x = (x << 3) + (x << 1) + c - '0';
c = getchar();
}
return x * f;
}
int T, n, m, k, tot, d, sum, l, r;
int b[N];
int main(){
T = read();
while (T --) {
bool f = true;
n = read(), k =read(), m = read();
for (int i = 1; i <= m; i ++)
b[i] = read();
if ((n - m) % (k - 1) != 0) {//无解
printf("NO\n");
continue;
}
tot = 1; d = (k - 1) / 2; sum = n;
for (int i = 1; i <= m; i ++)
{
if (b[i] - i >= d && n - b[i] - m + i >= d){//判断是否有一个数满足条件
printf("YES\n");f = false;
break;
}
}
if(f) printf("NO\n");//如果这个数不存在,仍无解
}
return 0;
}
原文地址:https://www.cnblogs.com/1314cqy/p/15119226.html
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法