题目:

  给出 k 和 n 个数,构造一个序列使得 d[i]>=d[i/k] ,并且字典序最大。

分析:

  听说,当年省选的时候,这道题挡住了大批的高手,看上去十分简单,实际上那道弯段时间内是转不过来的。

  首先,一个套路是,将这个序列的关系抽象成一棵树,i的父亲是floor(i/k),我们要要求子树内部的点的权值都比父亲大。

  我们观察子任务的特殊限制,di不一样?

  我们想,把原序列从大到小排序,在树上dfs给点赋值,在给一个点赋值时,要在序列上预留出siz[这棵子树]的位置,用来给子树内部的点赋值(排序就是为了方便在序列上预留位置)。

  但是,如果有重复的元素就办不了了,比如n=4, k=2 序列是1,1,1,2.

  排好应该是1 1 2 1,但是我们上面的方法会排成1 1 1 2

  为什么呢?

  我们从大到小排序,应该得到2 1 1 1.我们递归,首先是树根节点,需要预留4个位置,所以肯定要选最后一个(1),然后递归到第一个子树(序号为2),size为2,需要在这个子树留两个位置,所以我们把第二个1给了序号2这个位置,然后那个2就给了它的儿子(序号4)但是实际上,我们可以给它留一个1,把这个4给位置3.

  我这么分析会很乱,但是我们于情于理考虑一下,我们解决完了位置2,若想字典序最大,我们应该先最大化3这个位置。

  所以我们应该在给序号2找到最大值之后,应该为他的子树预留一些值,使这些值在合法的基础上尽可能小。

  所以我们应该排序后,建立一个序列c,c[i]的值代表排好序的序列上,i及i左边的所有值还剩下多少个可以选的。

  (序列c一开始肯定是1,2,3,4,5……)

  然后我们每次为一个点赋值,应该找到最靠左的一个位置i,使所有j>=i满足c[j]>=siz[这个点的子树]。

  并且选完之后,要找到这个位置往右最右边和他值相等的那个位置(前提是没有被用过的)。

  然后,用区间减法计算贡献,之后接着处理这个点的兄弟节点,没有了兄弟节点之后在进入某个点的子节点。

  进入一个子节点时,要将之前预留的位置(区间减去的数值)加回来,但是已经分配出去的(父亲的)权值就不要加回来了。

  所以是siz-1

代码:

 #include<bits/stdc++.h>
#define db double
using namespace std;
const int N=,inf=1e9;
struct segtree{
int l,r,ls,rs,mn,lz;
}t[N*];int a[N],b[N],ans[N],m,rt;
db k;int n,siz[N],fa[N],cnt[N],o=;
bool cmp(int u,int v){return u>v;}
void pushup(int cur){
int ls=t[cur].ls,rs=t[cur].rs;
t[cur].l=t[ls].l;t[cur].r=t[rs].r;
t[cur].mn=min(t[ls].mn,t[rs].mn);
} void pushdown(int cur){
int ls=t[cur].ls,rs=t[cur].rs,d=t[cur].lz;
t[ls].mn+=d;t[ls].lz+=d;
t[rs].mn+=d;t[rs].lz+=d;
t[cur].lz=;return ;
} void build(int x,int l,int r){
if(l==r){
t[x].l=t[x].r=l;t[x].ls=t[x].rs=-;
t[x].mn=l;return ;
} int mid=l+r>>;
t[x].ls=o++;t[x].rs=o++;
build(t[x].ls,l,mid);build(t[x].rs,mid+,r);
pushup(x);return ;
} void update(int x,int l,int r,int c){
if(l<=t[x].l&&t[x].r<=r)
{t[x].mn+=c;t[x].lz+=c;return ;}
pushdown(x);int mid=t[x].l+t[x].r>>;
if(l<=mid) update(t[x].ls,l,r,c);
if(mid<r) update(t[x].rs,l,r,c);
pushup(x);return ;
} int query(int x,int p){
if(t[x].l==t[x].r)
return t[x].mn>=p?t[x].l:t[x].l+;
pushdown(x);int mid=t[x].l+t[x].r>>;
if(p<=t[t[x].rs].mn) return query(t[x].ls,p);
else return query(t[x].rs,p);return ;
} int main(){
scanf("%d%lf",&n,&k);rt=o++;
for(int i=;i<=n;i++) scanf("%d",&a[i]);
sort(a+,a++n,cmp);build(rt,,n);
for(int i=n-;i;i--)
if(a[i]==a[i+]) cnt[i]=cnt[i+]+;
else cnt[i]=;
for(int i=;i<=n;i++)
fa[i]=(int)floor(i/k),siz[i]=;
for(int i=n;i;i--) siz[fa[i]]+=siz[i];
for(int i=;i<=n;i++){
if(fa[i]&&fa[i]!=fa[i-])
update(rt,ans[fa[i]],n,siz[fa[i]]-);
int x=query(rt,siz[i]);ans[i]=x;
x+=cnt[x];cnt[x]++;x-=(cnt[x]-);
update(rt,x,n,-siz[i]);
} for(int i=;i<=n;i++)
printf("%d ",a[ans[i]]);
return ;
}

贪心+线段树

[九省联考2018] IIIDX 线段树+贪心的更多相关文章

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

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

  2. BZOJ5249 九省联考2018IIIDX(线段树+贪心)

    显然这形成了一个树形结构.考虑这样一种贪心:按照曲目顺序,每次取消其父亲的预留,并选择当前可选择(保证其子树有合法选择且满足预留)的最大值,然后对其子树预留出大于等于他的一些值.这个做法显然是正确的. ...

  3. 省选九省联考T2 IIIDX(线段树)

    题目传送门:https://www.luogu.org/problemnew/show/P4364 期中考后记:期中考刚考完,感觉不咋滴,年排第3.我抗压力太差了..期末得把rank1抢回来. 本来感 ...

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

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

  5. [BZOJ 5252][LOJ 2478][九省联考2018] 林克卡特树

    [BZOJ 5252][LOJ 2478][九省联考2018] 林克卡特树 题意 给定一个 \(n\) 个点边带权的无根树, 要求切断其中恰好 \(k\) 条边再连 \(k\) 条边权为 \(0\) ...

  6. 洛谷P4364 [九省联考2018]IIIDX 【线段树】

    题目 [题目背景] Osu听过没?那是Konano最喜欢的一款音乐游戏,而他的梦想就是有一天自己也能做个独特酷炫的音乐游戏.现在 ,他在世界知名游戏公司KONMAI内工作,离他的梦想也越来越近了.这款 ...

  7. BZOJ.5249.[九省联考2018]iiidx(贪心 线段树)

    BZOJ LOJ 洛谷 \(d_i\)不同就不用说了,建出树来\(DFS\)一遍. 对于\(d_i\)不同的情况: Solution 1: xxy tql! 考虑如何把这些数依次填到树里. 首先对于已 ...

  8. [九省联考2018]IIIDX 贪心 线段树

    ~~~题面~~~ 题解: 一开始翻网上题解看了好久都没看懂,感觉很多人都讲得不太详细,所以导致一些细节的地方看不懂,所以这里就写详细一点吧,如果有不对的or不懂的可以发评论在下面. 首先有一个比较明显 ...

  9. [九省联考2018]IIIDX

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

随机推荐

  1. 阿里云物联网 .NET Core 客户端 | CZGL.AliIoTClient:4. 设备上报属性

    文档目录: 说明 1. 连接阿里云物联网 2. IoT 客户端 3. 订阅Topic与响应Topic 4. 设备上报属性 4.1 上报位置信息 5. 设置设备属性 6. 设备事件上报 7. 服务调用 ...

  2. jsp 预编译

    jspc-maven-plugin <?xml version="1.0" encoding="UTF-8"?> <project xmlns ...

  3. Jquery | 基础 | 项目实践

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  4. Qt 2D绘图之三:绘制文字、路径、图像、复合模式

    一.绘制文字 除了绘制图形以外,还可以使用QPainter::darwText()函数来绘制文字,也可以使用QPainter::setFont()设置文字所使用的字体,使用QPainter::font ...

  5. Linux之文本处理命令

    Sort 将文件的每一行作为一个单位,相互比较,比较原则是从首字符向后,依次按ASCII码值进行比较,最后将他们按升序输出. -u     在输出行中去除重复行 -r      改为降序(默认升序) ...

  6. 解决thymeleaf严格html5校验的方法

    用的是springboot加thyemleaf做静态模板. 然后会有个很烦的东西,就这个静态模板对html的格式非常严格,导致很多框架的格式都用不了,然后这里有个解除的方法: 1.在pom中添加依赖: ...

  7. ubuntu 文件解压命令

    [解压.zip文件] unzip ./FileName.zip //前提是安装了unzip 安装unzip命令:sudo apt-get install unzip 卸载unzip软件 命令:sudo ...

  8. 关于nodejs模块安装后找不到包解决办法

    主要原因是类似bower.gulp这些包后,没有添加到环境变量,但是有洁癖的我也不希望添加太多的软链接,所以在用phpstorm开始时有需要的情况下 定义临时的环境变量 http://stackove ...

  9. 【algorithm】二叉树的遍历

    二叉树的遍历 二叉树用例 代码解析: public class BinaryTree { static class TreeNode { Integer val; TreeNode left; Tre ...

  10. bootstrap基本组件

    bootstrap分页   <nav>      <ul class="pagination">       <li><a href=&q ...