题目大意:

给出k、n个数选择一种字典序最大的排列,使得对于任意的i,di>=d[i/k](下取整 下同)

分析:

很容易想到的是建树,将i的父亲设为[i/k],之后建有向边。

60分贪心:

将原先的a数组升序排列,直接根据子树大小分配排位。pai[i]=(同层级剩余的)-(子树大小)+1; 然而对于di有相同的情况时,也许可能会使得子树之间值发生交换,仍使得命题成立。

例如: [1,2,2,3] k=2;

正解:[1,2,3,2]

贪心: [1,2,2,3]

问题在于,因为题目中说了满足单调不降即可,而贪心则极力向后取数,可能会将大的数预留给自己较大编号的后代。如这个例子中,2号取到了3号排位,将4号排位、最大的3留给了4号。而3号就只剩下了2号排位。

我们想最大化较小的编号的值,就让它尽量往后取排位。 但是由于单调不降,可以让2号取2号位,4号取3号位,3号取4号位。使得答案更优。

正解:

线段树。

令原数组a降序排列。 令f[i]表示i号排位左边还有几个位置上的数是可以取到的。线段树维护这个区间内f的最小值。

显然这个f数组单调不降。对于从小到大的第i个编号,我们每次二分一个x,使得找到一个最靠左的位置,使得f[x]>=size[i],若有多个x,找到最靠右的一个x(这样使得在x取值最优时,尽可能将大的数留给后面的数。)让[x~n]区间上的值都减去size[i]

具体实现:

1.先判断到了i号点时,有没有进入下一个层级,如果有,将上一个层级预留的值都加回来(+size[fa]-1),才能二分、利用。

2.二分找到一个p;将p移动到同一个数值的、未用过的最右边。

3.将p赋值给ans[i],记录该p已经被用过(详见代码中nxt[p]++,这样保证下次减回来能多减一个位置

4.给子树预留位置。

详见代码:

#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
const int N=+;
int nxt[N],a[N],ans[N],fa[N],size[N];
int n;
double k;
struct node{
int mi,l,r;
int add;
#define mix t[x].mi
#define lx t[x].l
#define rx t[x].r
#define lsx x<<1
#define rsx x<<1|1
#define ax t[x].add
#define milsx t[lsx].mi
#define mirsx t[rsx].mi
#define alsx t[x<<1].add
#define arsx t[x<<1|1].add
}t[N<<];
void push(int x)
{
if(!ax) return;
milsx+=ax;
mirsx+=ax;
alsx+=ax;
arsx+=ax;
ax=;
}
void build(int l,int r,int x)
{
if(l==r)
{
mix=l,lx=l,rx=r;ax=;return;
}
int mid=(l+r)>>;
lx=l,rx=r,ax=;
build(l,mid,lsx);
build(mid+,r,rsx);
mix=min(mirsx,milsx);
}
void add(int l,int r,int x,int c)
{
if(l<=lx&&rx<=r)
{
mix+=c;
ax+=c;return;
}
push(x);
int mid=(lx+rx)>>;
if(l<=mid) add(l,r,lsx,c);
if(mid<r) add(l,r,rsx,c);
mix=min(milsx,mirsx);
}
int find(int x,int d)
{
if(lx==rx) return lx+(mix<d);
push(x);
if(mirsx<d) return find(rsx,d);
return find(lsx,d);
}
bool cmp(int a,int b) {return a>b;}
void prework()
{
sort(a+,a+n+,cmp);
for(int i=;i<=n;i++)
fa[i]=int(i/k),size[i]=;
for(int i=n-;i;i--)
if(a[i]==a[i+]) nxt[i]=nxt[i+]+;
for(int i=n;i;i--)
size[fa[i]]+=size[i]; }
int main()
{
scanf("%d%lf",&n,&k);
for(int i=;i<=n;i++)
scanf("%d",&a[i]);
prework();
int root=;
build(,n,root);
for(int i=;i<=n;i++)
{
if(fa[i]!=fa[i-]) add(ans[fa[i]],n,root,size[fa[i]]-);
int p=find(root,size[i]);
p+=nxt[p];nxt[p]++;p-=nxt[p]-;ans[i]=p;
add(p,n,root,-size[i]);
}
for(int i=;i<=n;i++)
printf("%d ",a[ans[i]]);
return ;
}

2018 省选 D1T2 IIIDX的更多相关文章

  1. 2018 省选 T1 一双木棋

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

  2. [游记] Noip 2018

    飞雪连天射白鹿, 笑书神侠倚碧鸳 $ 2018/12/14 $ 经历了 \(noip\) 玩完的心态爆炸之后,还是决定稍微写一下游记记录一下\(QAQ\),以免以后就忘了. 然后打算先写个框架之后再慢 ...

  3. 【科技】KD-tree随想

    大概就是个复杂度对的暴力做法,在你不想写二维线段树等的时候优秀的替代品. 优点:思路简单,代码好写. 他大概有两种用法(虽然差不多). 在平面坐标系中干一些事情: 例如最常规的平面最近最远点,不管是欧 ...

  4. 一双木棋(chess)

    一双木棋(chess) 题目描述 菲菲和牛牛在一块 nn 行 mm 列的棋盘上下棋,菲菲执黑棋先手,牛牛执白棋后手. 棋局开始时,棋盘上没有任何棋子,两人轮流在格子上落子,直到填满棋盘时结束.落子的规 ...

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

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

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

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

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

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

  8. [luogu] P4364 [九省联考2018]IIIDX(贪心)

    P4364 [九省联考2018]IIIDX 题目背景 Osu 听过没?那是Konano 最喜欢的一款音乐游戏,而他的梦想就是有一天自己也能做个独特酷炫的音乐游戏.现在,他在世界知名游戏公司KONMAI ...

  9. [九省联考2018]IIIDX

    题目描述 这一天,Konano接到了一个任务,他需要给正在制作中的游戏<IIIDX>安排曲目的解锁顺序.游戏内共有n首曲目 ,每首曲目都会有一个难度d,游戏内第i首曲目会在玩家Pass第t ...

随机推荐

  1. BodeAbp服务端介绍

    BodeAbp服务端只提供api,绝大部分api通过abp的动态WebApi机制提供,原理可以参考这篇文章:http://www.cnblogs.com/1zhk/p/5418694.html 与业务 ...

  2. Jmeter(非GUI模式)教程

    前言 使用非 GUI 模式,即命令行模式运行 JMeter 测试脚本能够大大缩减所需要的系统资源.优点如下:1.节约系统资源:无需启动界面,节约系统资源 2.便捷快速:仅需启动命令行,输入命令便可执行 ...

  3. C_数据结构_递归不同函数间调用

    # include <stdio.h> void f(); void g(); void k(); void f() { printf("FFFF\n"); g(); ...

  4. Linux内核设计与实现 第四章

    1. 什么是调度 现在的操作系统都是多任务的,为了能让更多的任务能同时在系统上更好的运行,需要一个管理程序来管理计算机上同时运行的各个任务(也就是进程). 这个管理程序就是调度程序,功能: 决定哪些进 ...

  5. 语音笔记:MFCC

    一,传统语音识别体系结构 二,MFCC特征提取 MFCC(Mel-frequency cepstral coefficients):梅尔频率倒谱系数.梅尔频率是基于人耳听觉特性提出来的, 它与Hz频率 ...

  6. JAVA SOCKET编程单线程简单实例

    服务端: package socketProgram; import java.io.BufferedReader;import java.io.IOException;import java.io. ...

  7. Maven+SSM整合.doc

    Maven + SSM整合 1开发环境搭建 1.1Eclipse4.7(Oxygen) + Tomcat8 + Maven3.5.2 2Maven Web项目创建 2.1新建maven项目 2.2 选 ...

  8. 将J2EE的Web项目设置为支持Activiti

    <natures> <nature>org.eclipse.jem.workbench.JavaEMFNature</nature> <nature>o ...

  9. Node params和query的Get请求传参

    //1:加载http express框架//2:创建服务器const http = require("http");const express = require("ex ...

  10. pycharm5.0 快捷键大全osx

    官网链接https://resources.jetbrains.com/assets/products/pycharm/PyCharm_ReferenceCard_mac.pdf 一直想给别人安利py ...