题意

题目链接

Sol

不难发现题目给出的是一个树,其中\(\frac{i}{K}\)是\(i\)的父亲节点

首先,当\(d_i\)互不相同时,一个显然的贪心策略就是优先给编号小的分配较大的权值。可以排序后dfs完成。

但是,当\(d_i\)相同时,可能存在这样一种情况:把编号小的子树内权值较大的节点,和某个编号较大的根交换后,仍然满足要求

比如\(N = 4, K = 2, a = {1, 1, 1, 2}\)

此时直接贪心的话会输出\(1, 1, 1, 2\),实际上最优解为\(1, 1, 2, 1\)

这时候怎么办呢?

考虑一个节点\(p\)可以选择权值为\(x\)的条件是什么,因为该节点子树内的权值一定都比\(x\)大

因此对于每个权值小于\(x\)的数,权值比它大且可以选择的数至少为\(siz[p]\)个

同时根据贪心的策略,先遍历到的节点应该选大的权值。

这样就不难得到一个算法:

首先按权值从大到小排序,同时用线段树维护出每个位置权值比它大且能选择的位置个数

对于每个点\(p\),在线段树上二分出最大的满足条件的位置\(x\)。同时,当权值相同时,该位置应该更靠右。

然后再在区间\([x, n]\)中的所有点减去\(siz[x]\)

注意一个细节,当遍历到某个节点时,应该消去父亲对他的影响

写完代码 -> 过样例 -> 1A hhhhhh(虽然是抄的)

60分

#include<bits/stdc++.h>
#define sz(x) (int)x.size()
using namespace std;
const int MAXN = 5e5 + 10;
inline int read() {char c = getchar(); int x = 0, f = 1;while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();return x * f;
}
int N; double K;
int a[MAXN], ans[MAXN], res;
vector<int> v[MAXN];
int AddEdge(int x, int y) {v[x].push_back(y);
}
void dfs(int x) {for(int i = 0; i < sz(v[x]); i++) dfs(v[x][i]);if(x) ans[x] = a[res--];
}
int main() {scanf("%d%lf", &N, &K); res = N;//printf("%lf\n", K);for(int i = 1; i <= N; i++) {int pre = (int) floor(i / K);a[i] = read(); AddEdge(pre, i);}sort(a + 1, a + N + 1);dfs(0);for(int i = 1; i <= N; i++) printf("%d ", ans[i]);return 0;
}

AC代码

#include<bits/stdc++.h>
using namespace std;
const int MAXN = 5e5 + 10;
inline int read() {char c = getchar(); int x = 0, f = 1;while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();return x * f;
}
int N; double K;
int cnt[MAXN], fa[MAXN], siz[MAXN], ans[MAXN], a[MAXN];
#define ls k << 1
#define rs k << 1 | 1
struct Node {int l, r, f, mn;
}T[MAXN << 2];
void update(int k) {T[k].mn = min(T[ls].mn, T[rs].mn);
}
void add(int k, int val) {T[k].f += val; T[k].mn += val;
}
void pushdown(int k) {if(!T[k].f) return ;add(ls, T[k].f); add(rs, T[k].f); T[k].f = 0;
}
void Build(int k, int ll, int rr) {T[k] = (Node) {ll, rr, 0, 0};if(ll == rr) {T[k].mn = ll; return ;}int mid = ll + rr >> 1;Build(ls, ll, mid); Build(rs, mid + 1, rr); update(k);
}
void IntervalAdd(int k, int ll, int rr, int val) {if(ll <= T[k].l && T[k].r <= rr) {add(k, val); return ;}pushdown(k);int mid = T[k].l + T[k].r >> 1;if(ll <= mid) IntervalAdd(ls, ll, rr, val); if(rr  > mid) IntervalAdd(rs, ll, rr, val);update(k);
}
int Query(int k, int sz) {if(T[k].l == T[k].r) return T[k].mn >= sz ? T[k].l : T[k].l + 1;pushdown(k);if(T[rs].mn >= sz) return Query(ls, sz);else return Query(rs, sz);
}
int main() {N = read(); cin >> K;for(int i = 1; i <= N; i++) {a[i] = read();int t = (int) floor(i / K); fa[i] = t; siz[i] = 1;}for(int i = N; i >= 0; i--) siz[fa[i]] += siz[i];Build(1, 1, N); sort(a + 1, a + N + 1, greater<int>());for(int i = N - 1; i >= 1; i--) cnt[i] = (a[i] == a[i + 1] ? cnt[i + 1] + 1 : 0);for(int i = 1; i <= N; i++) {if(fa[i] && fa[i] != fa[i - 1]) IntervalAdd(1, ans[fa[i]], N, siz[fa[i]] - 1);int t = Query(1, siz[i]); t += cnt[t]; cnt[t]++; t -= (cnt[t] - 1); ans[i] = t;IntervalAdd(1, t, N, -siz[i]);}for(int i = 1; i <= N; i++) printf("%d ", a[ans[i]]);return 0;
}

BZOJ5249: [2018多省省队联测]IIIDX(线段树 贪心)相关推荐

  1. bzoj5252: [2018多省省队联测]林克卡特树

    题目链接 bzoj5252: [2018多省省队联测]林克卡特树 题解 tu优化! 其实之前做过类似的,思想类似,二分一个价值的偏移量来逼近限制k,大概是clj出的一道集训队胡策啥来着?? 对于本题, ...

  2. BZOJ 5249: [2018多省省队联测]IIIDX(贪心 + 线段树)

    题意 这一天,\(\mathrm{Konano}\) 接到了一个任务,他需要给正在制作中的游戏 \(\mathrm{<IIIDX>}\) 安排曲目 的解锁顺序.游戏内共有\(n\) 首曲目 ...

  3. bzoj5252 [2018多省省队联测]林克卡特树

    斜率优化树形dp?? 我们先将问题转化成在树上选K+1条互不相交路径,使其权值和最大. 然后我们考虑60分的dp,直接维护每个点子树内选了几条路径,然后该点和0/1/2条路径相连 然后我们会发现最后的 ...

  4. 2018.10.20 NOIP模拟 蛋糕(线段树+贪心/lis)

    传送门 听说是最长反链衍生出的对偶定理就能秒了. 本蒟蒻直接用线段树模拟维护的. 对于第一维排序. 维护第二维的偏序关系可以借助线段树/树状数组维护逆序对的思想建立权值线段树贪心求解. 代码 转载于: ...

  5. [BZOJ5249][九省联考2018]IIIDX(线段树)

    5249: [2018多省省队联测]IIIDX Time Limit: 40 Sec  Memory Limit: 512 MB Submit: 32  Solved: 17 [Submit][Sta ...

  6. bzoj5248 [2018多省省队联测]一双木棋

    5248: [2018多省省队联测]一双木棋 Time Limit: 20 Sec  Memory Limit: 512 MB Submit: 155  Solved: 132 [Submit][St ...

  7. bzoj 5248: [2018多省省队联测]一双木棋

    Description 菲菲和牛牛在一块n行m列的棋盘上下棋,菲菲执黑棋先手,牛牛执白棋后手.棋局开始时,棋盘上没有任何棋子, 两人轮流在格子上落子,直到填满棋盘时结束.落子的规则是:一个格子可以落子 ...

  8. Bzoj5251: [2018多省省队联测]劈配

    题面 传送门 Sol 网络流辣 枚举每个点的最优匹配,然后只建最优匹配的边跑网络流 下一个点的图中,保证上一个点只连了最优匹配的边 直接整个图复制过来 然后二分答案一个点向上跳多少 和上面一样建图\( ...

  9. BZOJ5248 [2018多省省队联测]一双木棋(状压+记忆化搜索)

    题目链接:BZOJ 5248 题目描述: 菲菲和牛牛在一块n行m列的棋盘上下棋(n,m<=10),菲菲执黑棋先手,牛牛执白棋后手.棋局开始时,棋盘上没有任何棋子,两人轮流在格子上落子,直到填满棋 ...

最新文章

  1. 使用Python,OpenCV从静态背景中提取移动前景
  2. C语言的内联函数的作用
  3. python绘制随机数直方图-用matplotlib画直方图(histogram)
  4. 实验10:创建带有生命周期方法的bean ||实验11:测试bean的后置处理器
  5. 如何修改Vs2008环境变量
  6. 特别推荐:系统性能提升优先法宝 | 缓存应用实践
  7. Spring在tomcat下使用JTA事务
  8. bz2解压命令_Linux文件操作之文件压缩与解压缩命令详解
  9. 翻转链表python递归_Python LeetCode-206.反转链表(难度-简单) 两个方法-迭代和递归,以及超简写法(python)...
  10. HTML 标题h1-h6
  11. TX2不支持TensorRT INT8,int8 官方参考
  12. 白话空间统计二十四:地理加权回归(一)
  13. 无法修改计算机时间权限,Win10无法修改时间怎么办?Win10修改系统时间没有权限的解决方法...
  14. 全网火爆高颜值蓝牙耳机,低延迟游戏党必备蓝牙耳机推荐
  15. 高端蓝牙耳机哪个牌子好?四款高音质不错的蓝牙耳机推荐
  16. 华为鸿蒙麒麟玉兔_华为“鸿蒙”实锤了!还有朱雀、麒麟、鲲鹏,网友:华为注册了一本《山海经》...
  17. bug记录-socket hang up
  18. 总谐波失真--THD
  19. JS键盘对应Code
  20. Single Application

热门文章

  1. linux bash shell之变量替换::=句法、=句法、:-句法、-句法、=?句法、?句法、:+句法、+句法
  2. android okhttp使用cookie请求
  3. 【JS】执行上下文(ExcecutionContext)
  4. ViewRoot:处理消息+WMS交互+控制DecorView
  5. [转] 小结js屏幕、浏览器、页面大小(三)———拖拽
  6. SDNU 1429.区间k大数查询(水题)
  7. [2019HDU多校第一场][HDU 6590][M. Code]
  8. 【算法】BitMap
  9. 基本数据类型对象包装类
  10. TCP连接之报文首部