目录
一、题目
1、题目描述
2、输入输出
2.1输入
2.2输出
3、原题链接
二、解题报告
1、思路分析
2、复杂度
3、代码详解
一、题目
1、题目描述
2、输入输出
2.1输入
2.2输出
3、原题链接
Problem - 720A - Codeforces
二、解题报告
1、思路分析
如果人都在左上角如何分配?
把人按照耐力排序,位置按照权值排序,从小到大分配,就变成了贪心入门问题中的给小孩分糖果问题
现在变成了两拨人,每个位置对两拨人有不同的权值,如何分配?
先把每拨人升序排序,然后先处理左边这拨人。
顺序遍历左部人,选取当前这个人能拿的位置中对右边那拨人最远的位置,这样有个好处:由于升序排序,所以当前人能拿的位置后面人也能拿,同时又保证了对右部人影响最小
对于位置的维护可以用set或者线段树
set不容易写错,但是为了练习下线段树还是用了线段树,结果调了1h x_x
2、复杂度
时间复杂度: O(mn logmn)空间复杂度:O(mn)
3、代码详解
#include <bits/stdc++.h>
const int N = 1e4 + 10;
#define lc p << 1
#define rc p << 1 | 1
typedef std::pair<int, int> PII;
int n, m, k, l, tot;
int dstk[N], dstl[N];
PII vk[N];
struct node {
int l, r, vl, id;
} tr[N << 4];
void pushup(int p) {
if(tr[lc].vl > tr[rc].vl)
tr[p].vl = tr[lc].vl, tr[p].id = tr[lc].id;
else
tr[p].vl = tr[rc].vl, tr[p].id = tr[rc].id;
}
void build(int p, int l, int r) {
tr[p] = { l, r, vk[l].second, l };
if (l == r) return;
int mid = l + r >> 1;
build(lc, l, mid), build(rc, mid + 1, r);
pushup(p);
}
void update(int p, int x, int v) {
if(tr[p].l == x && tr[p].r == x) {
tr[p].vl = tr[p].id = v;
return;
}
int mid = tr[p].l + tr[p].r >> 1;
if(x <= mid) update(lc, x, v);
else update(rc, x, v);
pushup(p);
}
PII query(int p, int l, int r) {
if (l <= tr[p].l && tr[p].r <= r) {
return std::make_pair(tr[p].id, tr[p].vl);
}
int mid = tr[p].l + tr[p].r >> 1;
PII res = std::make_pair(-1, -1);
if(l <= mid) {
PII t = query(lc, l, r);
if (t.second > res.second) res = t;
}
if(r > mid) {
PII t = query(rc, l, r);
if (t.second > res.second) res = t;
}
return res;
}
int find(int x) {
int l = 1, r = tot, res = 1;
while(l <= r) {
int mid = l + r >> 1;
if (vk[mid].first <= x) res = mid, l = mid + 1;
else r = mid - 1;
}
return res;
}
int main() {
std::ios::sync_with_stdio(false), std::cin.tie(0), std::cout.tie(0);
std::cin >> n >> m >> k;
for (int i = 0; i < k; i ++) std::cin >> dstk[i];
std::cin >> l;
for (int i = 0; i < l; i ++) std::cin >> dstl[i];
for (int i = 1; i <= n; i ++)
for (int j = 1; j <= m; j ++)
vk[++ tot] = std::make_pair(i + j, i + m + 1 - j);
std::sort(vk , vk + tot);
std::sort(dstk, dstk + k), std::sort(dstl, dstl + l);
build(1, 1, tot);
for (int i = 0; i < k; i ++) {
int r = find(dstk[i]);
PII t = query(1, 1, r);
if (t.second == -1) {
std::cout << "NO";
return 0;
}
update(1, t.first, -1);
}
std::vector<int> res;
res.reserve(tot);
for(int i = 1; i <= tot; i ++) {
PII t = query(1, i, i);
if(~t.second)
res.push_back(t.second);
}
std::sort(res.begin(), res.end());
for (int i = 0, t = 0; i < l; i ++) {
if (t > res.size() || dstl[i] < res[t]) {
std::cout << "NO";
return 0;
}
t ++;
}
std::cout << "YES";
return 0;
}