BZOJ_5249_[2018多省省队联测]IIIDX_线段树

Description

【题目背景】
Osu听过没?那是Konano最喜欢的一款音乐游戏,而他的梦想就是有一天自己也能做个独特酷炫的音乐游戏。现在,他在世界知名游戏公司KONMAI内工作,离他的梦想也越来越近了。这款音乐游戏内一般都包含了许多歌曲,歌曲越多,玩家越不易玩腻。同时,为了使玩家在游戏上氪更多的金钱花更多的时间,游戏一开始一般都不会将所有曲目公开,有些曲目你需要通关某首特定歌曲才会解锁,而且越晚解锁的曲目难度越高。
【题目描述】
这一天,Konano接到了一个任务,他需要给正在制作中的游戏《IIIDX》安排曲目的解锁顺序。游戏内共有n首曲目,每首曲目都会有一个难度d,游戏内第i首曲目会在玩家Pass第$\lfloor i/k \rfloor$首曲目后解锁(x为下取整符号)若$\lfloor i/k \rfloor =0$,则说明这首曲目无需解锁。举个例子:当k=2时,第1首曲目是无需解锁的($\lfloor 1/2 \rfloor =0$),第7首曲目需要玩家Pass第$\lfloor 7/2 \rfloor =3$首曲目才会被解锁。Konano的工作,便是安排这些曲目的顺序,使得每次解锁出的曲子的难度不低于作为条件需要玩家通关的曲子的难度,即使得确定顺序后的曲目的难度对于每个i满足Di≥$\lfloor i/k \rfloor$ 。当然这难不倒曾经在信息学竞赛摸鱼许久的Konano。那假如是你,你会怎么解决这份任务呢

Input

第1行1个正整数n和1个小数k,n表示曲目数量,k其含义如题所示。
第2行n个用空格隔开的正整数d,表示这n首曲目的难度。
1 ≤ n ≤ 500000
1 < k ≤ 10^9
1 < d ≤ 10^9

Output

输出1行n个整数,按顺序输出安排完曲目顺序后第i首曲目的难度。
若有多解,则输出d1最大的;若仍有多解,则输出d2最大的,以此类推。

Sample Input

4 2.0
114 514 1919 810

Sample Output

114  810  514  1919
 

首先可以发现题目给出的关系是一棵森林,而我们要给森林中的每个节点权值,使得每个节点的权值都要小于等于子树内任何一点的权值,并且使权值字典序最大。
建一个虚点向所有$i < k$的点连边,于是森林就成了一棵树,并处理出子树的大小$siz$。
把权值从大到小排序,对于每个点,我要选当前剩下的权值里第$siz$大的,然后给子树预定这个点前面的权值,递归处理。
这是一种错误的贪心,错误数据
4 2.0
1 1 1 2
答案是1 1 2 1而错误的贪心输出1 1 1 2。
当权值各不相同的时候这个贪心是对的,因为第$siz$大的就是我们要的,子树用比它大的那$siz-1$个即可。
而如果权值有重复的,我们要找和第$siz$大的权值相等的权值中最靠右的那个点,再给子树预定$siz-1$个,这样做能够让当前点权值尽可能大的前提下给子树预定的权值尽可能的小,这样,万一下一个要分配的点不在这个点的子树中,也能被分配尽可能大的权值。
怎么操作呢?
设$F[i]$为第i个权值左边有多少个没被预定,即可用数量。初始值$F[i]=i$。我们在线段树上维护$F[i]$和$F[i]$的最大值。
举个官方题解中的例子:9 8 7 6 5 5 5 5 5 4 3 2
假如第一个结点的子树大小为7,那么第一个结点的权值就应该是第7大的数。
初始时$F[i]=i$,我们发现$F[12]>F[11]>F[10]>F[9]>F[8]>F[7]=7$,即第$7$个点右侧的可用数量都大于$7$,我们刚好应该选择第$7$个数$5$,同时让被选的$5$的位置尽可能的靠右,于是选到了第$9$的位置。(具体做法:每个相等的值有一个$cnt$值,当前位置$x$加上$cnt[x]$刚好是权值为$a[x]$的数中最右的位置,再处理出这个位置上的数已经被拿了多少次,从$x$中减掉)。
接着第一个节点要给它的子树预定$siz-1$个位置,但我们不好确定是哪几个位置,于是$F[9]\thicksim F[n]$都减去$(siz-1)$即可。
对于其他结点$i$重复上述操作:
$1$.找到一个位置尽可能靠前的$x$,满足$x$右边的所有$F[]$都大于等于$siz[i]$。这步查询在线段树上二分即可。
$2.$找到权值为$a[x]$中剩下的最右的位置$y$满足$a[y]=a[x]$,并把$a[y]$分配给这个点。
$3.F[y]\thicksim F[n]$减去$(siz-1)$
注意处理到某个点,如果这个点的父亲的预定区间没有被撤销,需要撤销。
 
代码:
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <math.h>
using namespace std;
#define N 500050
#define ls p<<1
#define rs p<<1|1
typedef double du;
int fa[N],siz[N],n,cnt[N],a[N],t[N<<2],del[N<<2],ans[N];
du k;
bool used[N];
bool cmp(int x,int y){return x>y; }
void build(int l,int r,int p) {
if(l==r) {
t[p]=l; return ;
}
int mid=(l+r)>>1;
build(l,mid,ls); build(mid+1,r,rs);
t[p]=min(t[ls],t[rs]);
}
void pushdown(int p) {
if(del[p]) {
del[ls]+=del[p]; t[ls]+=del[p];
del[rs]+=del[p]; t[rs]+=del[p];
del[p]=0;
}
}
void update(int l,int r,int x,int y,int v,int p) {
if(x<=l&&y>=r) {
t[p]+=v; del[p]+=v;
return ;
}
pushdown(p);
int mid=(l+r)>>1;
if(x<=mid) update(l,mid,x,y,v,ls);
if(y>mid) update(mid+1,r,x,y,v,rs);
t[p]=min(t[ls],t[rs]);
}
int query(int l,int r,int x,int p) {
if(l==r) return t[p]>=x?l:l+1;
pushdown(p);
int mid=(l+r)>>1;
if(t[rs]>=x) return query(l,mid,x,ls);
else return query(mid+1,r,x,rs);
}
int main() {
scanf("%d%lf",&n,&k);
int i;
for(i=1;i<=n;i++) scanf("%d",&a[i]),siz[i]=1;
sort(a+1,a+n+1,cmp);
for(i=n-1;i>=1;i--) {
if(a[i]==a[i+1]) cnt[i]=cnt[i+1]+1;
else cnt[i]=0;
}
for(i=1;i<=n;i++) {
fa[i]=(int) floor(i/k);
}
for(i=n;i;i--) siz[fa[i]]+=siz[i];
build(1,n,1);
for(i=1;i<=n;i++) {
if(fa[i]&&!used[fa[i]]) {
update(1,n,ans[fa[i]],n,siz[fa[i]]-1,1);
used[fa[i]]=1;
}
int x=query(1,n,siz[i],1);
x+=cnt[x]; cnt[x]++; x-=(cnt[x]-1); ans[i]=x;
update(1,n,x,n,-siz[i],1);
}
int flg=0;
for(i=1;i<=n;i++) {
if(!flg) flg=printf("%d",a[ans[i]]);
else printf(" %d",a[ans[i]]);
}
}

BZOJ_5249_Luogu_P4364_[2018多省省队联测]_IIIDX_九省联考2018_JLOI2018_线段树的更多相关文章

  1. 5249: [2018多省省队联测]IIIDX

    5249: [2018多省省队联测]IIIDX 链接 分析: 贪心. 将给定的权值从大到小排序,从第一个往后挨个赋值,考虑第i个位置可以赋值那些树.首先满足前面必须至少有siz[i]个权值没选,如果存 ...

  2. bzoj 5249 [2018多省省队联测] IIIDX

    bzoj 5249 [2018多省省队联测] IIIDX Link Solution 首先想到贪心,直接按照从大到小的顺序在后序遍历上一个个填 但是这样会有大问题,就是有相同的数的时候,会使答案不优 ...

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

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

  4. [BZOJ5251][九省联考2018]劈配(网络流)

    5251: [2018多省省队联测]劈配 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 33  Solved: 22[Submit][Status][ ...

  5. [BZOJ5250][九省联考2018]秘密袭击(DP)

    5250: [2018多省省队联测]秘密袭击 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 3  Solved: 0[Submit][Status][D ...

  6. [BZOJ5248][九省联考2018]一双木棋(连通性DP,对抗搜索)

    5248: [2018多省省队联测]一双木棋 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 43  Solved: 34[Submit][Status ...

  7. [九省联考2018]秘密袭击coat

    [九省联考2018]秘密袭击coat 研究半天题解啊... 全网几乎唯一的官方做法的题解:链接 别的都是暴力.... 要是n=3333暴力就完了. 一.问题转化 每个联通块第k大的数,直观统计的话,会 ...

  8. 【BZOJ5250】[九省联考2018]秘密袭击(动态规划)

    [BZOJ5250][九省联考2018]秘密袭击(动态规划) 题面 BZOJ 洛谷 给定一棵树,求其所有联通块的权值第\(k\)大的和. 题解 整个\(O(nk(n-k))\)的暴力剪剪枝就给过了.. ...

  9. 「九省联考 2018」IIIDX 解题报告

    「九省联考 2018」IIIDX 这什么鬼题,送的55分要拿稳,实测有60? 考虑把数值从大到小摆好,每个位置\(i\)维护一个\(f_i\),表示\(i\)左边比它大的(包括自己)还有几个数可以选 ...

随机推荐

  1. 你不知道你不懂javascript

    过去几年我注意到技术圈一个很奇怪的现象,有太多程序员将那些他们只是有过非常浅显的了解, 但其实根本就不懂的技术写到他们的简历中,这个现象几乎每种语言都有,但这其中最严重的就要数javascript了. ...

  2. Memcache 运行情况

    Memcache Memcache是danga.com的一个开源项目,它是一个高性能的分布式的内存对象缓存系统,通过在内存里维护一个统一的巨大的Hash表,能够用来存储各种格式的数据. 查看当前的me ...

  3. 前端技术之_CSS详解第六天--完结

    前端技术之_CSS详解第六天--完结 一.复习第五天的知识 a标签的伪类4个: a:link 没有被点击过的链接 a:visited 访问过的链接 a:hover 悬停 a:active 按下鼠标不松 ...

  4. JQuery DOM操作 、属性和CSS样式操作、其他函数

    DOM操作 1.在div1内部最后追加一个节点 $("#div1").append("<img src='../01-HTML基本标签/img/Male.gif'/ ...

  5. ffmpeg 时间戳处理

    视频的显示和存放原理 对于一个电影,帧是这样来显示的:I B B P.现在我们需要在显示B帧之前知道P帧中的信息.因此,帧可能会按照这样的方式来存储:IPBB.这就是为什么我们会有一个解码时间戳和一个 ...

  6. Win7下 Python中文正则的奇异表现

    首先贴Win32下的直接Python shell下的测试结果: Python 2.7.6 (default, Nov 10 2013, 19:24:18) [MSC v.1500 32 bit (In ...

  7. 基类包括字段“ScriptManager1”,但其类型(System.Web.UI.ScriptManager)与控件(System.Web.UI.ScriptManager)的类型不兼容

    首先说下原先的情况,就是原本老项目的Web解决方案是使用.net framework 2.0的老版本, 所以机器也安装过Microsoft ASP.NET 2.0 AJAX Extensions..A ...

  8. Fiddler抓包使用教程-Android应用抓包

    转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/74439165 本文出自[赵彦军的博客] Fiddler 也可以支持对手机应用进行 ...

  9. 分布式服务通讯框架XXL-RPC

    <分布式服务通讯框架XXL-RPC>    一.简介 1.1 概述 XXL-RPC 是一个分布式服务通讯框架,提供稳定高性能的RPC远程服务调用功能.现已开放源代码,开箱即用. 1.2 特 ...

  10. 万网主机使用wordpress发送邮件的方法

    今天弄了一下午总算明白了,这里写一下具体过程. 首先是邮箱,万网主机是不支持mail()函数的,所以默认的不可用,如果你想发送邮件的话,只能使用fsockopen()函数.首先进入万网主机管理平台,启 ...