1364 最大字典序排列
基准时间限制:1 秒 空间限制:131072 KB 分值: 80 难度:5级算法题

给出一个1至N的排列,允许你做不超过K次操作,每次操作可以将相邻的两个数交换,问能够得到的字典序最大的排列是什么?

例如:N = 5, {1 2 3 4 5},k = 6,在6次交换后,能够得到的字典序最大的排列为{5 3 1 2 4}。
Input
第1行:2个数N, K中间用空格分隔(1 <= N <= 100000, 0 <= K <= 10^9)。
第2至N + 1行:每行一个数i(1 <= i <= N)。
Output
输出共N行,每行1个数,对应字典序最大的排列的元素。
Input示例
5 6
1
2
3
4
5
Output示例
5
3
1
2
4
/*
51nod 1364 最大字典序排列(线段树) problem:
给出一个1至N的排列,允许你做不超过K次操作,每次操作可以将相邻的两个数交换,问能够得到的字典序最大的排列是什么?
例如:N = 5, {1 2 3 4 5},k = 6,在6次交换后,能够得到的字典序最大的排列为{5 3 1 2 4}。 solve:
贪心的思想. 从1~n维护第i个数尽可能大. 就成了在[i+1,k+i]中查找最大值. 然后把找到的数从后面的数组中删除插到前面.
因为我的删除是用num来表示,所以每次都要先找到对应区间的边界位置. 然后在计算移动过去需要多少步. 直到操作结束 hhh-2016/09/04-11:16:36
*/
#pragma comment(linker,"/STACK:124000000,124000000")
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <vector>
#include <math.h>
#include <queue>
#include <set>
#include <map>
#define lson i<<1
#define rson i<<1|1
#define ll long long
#define clr(a,b) memset(a,b,sizeof(a))
#define scanfi(a) scanf("%d",&a)
#define scanfs(a) scanf("%s",a)
#define scanfl(a) scanf("%I64d",&a)
#define scanfd(a) scanf("%lf",&a)
#define key_val ch[ch[root][1]][0]
#define eps 1e-7
#define inf 0x3f3f3f3f3f3f3f3f
using namespace std;
const ll mod = 1000000007;
const int maxn = 100010;
const double PI = acos(-1.0);
int n;
int a[maxn];
struct node
{
int l,r,mid;
int pos,num;
int Max;
} tree[maxn<<2]; void push_up(int i)
{
if(tree[lson].Max >= tree[rson].Max)
{
tree[i].Max= tree[lson].Max;
tree[i].pos = tree[lson].pos;
}
else
{
tree[i].Max = tree[rson].Max;
tree[i].pos = tree[rson].pos;
}
tree[i].num = tree[lson].num + tree[rson].num;
} void build(int i,int l,int r)
{
tree[i].l = l,tree[i].r = r;
tree[i].mid = (l+r) >>1;
tree[i].num = 0;
if(l == r && l)
{
tree[i].num = 1;
tree[i].Max= a[l];
tree[i].pos = l;
return ;
}
build(lson,l,tree[i].mid);
build(rson,tree[i].mid+1,r);
push_up(i);
}
int tMax,tpos; void update(int i,int k)
{
if(tree[i].l >= k && tree[i].r <= k)
{
tree[i].Max = 0;
tree[i].num = 0;
return ;
}
int mid = tree[i].mid;
if(k <= mid)
update(lson,k);
else
update(rson,k);
push_up(i);
return ;
}
void query(int i,int l,int r)
{
if(tree[i].l >= l && tree[i].r <= r)
{
if(tMax < tree[i].Max)
tMax = tree[i].Max,tpos = tree[i].pos;
else if(tMax == tree[i].Max)
tpos = min(tree[i].pos,tpos);
return ;
}
int mid = tree[i].mid;
if(l <= mid)
query(lson,l,r);
if(r > mid)
query(rson,l,r);
push_up(i);
return ;
} int query_x(int i,int k)
{
if(tree[i].l == tree[i].r)
{
return tree[i].l;
}
int mid = tree[i].mid;
if(tree[lson].num >= k)
return query_x(lson,k);
else
return query_x(rson,k-tree[lson].num);
push_up(i);
} int query_num(int i,int l,int r)
{
if(tree[i].l >= l && tree[i].r <= r)
{
return tree[i].num;
}
int ans = 0;
if(l <=tree[i].mid)
ans += query_num(lson,l,r);
if(r > tree[i].mid)
ans += query_num(rson,l,r);
return ans;
} int ans[maxn];
int main()
{
int t;
// freopen("in.txt","r",stdin);
while(scanfi(n) != EOF)
{
scanfi(t);
a[0] = 0;
for(int i = 1; i <= n; i++)
{
scanfi(a[i]);
}
build(1,1,n);
int cnt = 1;
while(t > 0 && cnt <= n)
{
tMax = 0,tpos = n;
if(cnt + t >= n)
{
query(1,1,n);
update(1,tpos);
t -= query_num(1,1,tpos); printf("%d\n",tMax);
cnt++;
a[tpos] = -1;
}
else
{
int pos = query_x(1,t+1);
query(1,1,pos);
update(1,tpos);
t -= query_num(1,1,tpos);
cnt++;
printf("%d\n",tMax);
a[tpos] = -1;
}
}
for(int i = 1; i <= n; i++)
if(a[i] != -1)
printf("%d\n",a[i]);
}
return 0;
}

  

51nod 1364 最大字典序排列(线段树)的更多相关文章

  1. 51Node 1364--- 最大字典序排列(树状数组)

    51Node  1364--- 最大字典序排列(树状数组) 1364 最大字典序排列 基准时间限制:1 秒 空间限制:131072 KB 分值: 80 难度:5级算法题  收藏  关注 给出一个1至N ...

  2. 51nod 1463 找朋友(线段树+离线处理)

    http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1463 题意: 思路: 好题! 先对所有查询进行离线处理,按照右区间排序, ...

  3. 51nod 1494 选举拉票 | 线段树

    51nod1494 选举拉票 题面 现在你要竞选一个县的县长.你去对每一个选民进行了调查.你已经知道每一个人要选的人是谁,以及要花多少钱才能让这个人选你.现在你想要花最少的钱使得你当上县长.你当选的条 ...

  4. 51nod 1081 子段求和(线段树 | 树状数组 | 前缀和)

    题目链接:子段求和 题意:n个数字序列,m次询问,每次询问从第p个开始L长度序列的子段和为多少. 题解:线段树区间求和 | 树状数组区间求和 线段树: #include <cstdio> ...

  5. 51nod 1480 打广告(二分+线段树)

    题意 给出n个区间和m个区间,从这n个区间里选一个区间a,这m个区间选一个区间b,使得a&b的长度*c最大. 思路 如果这n个区间里有一个区间包含另一个区间,那另外一个区间就可以忽略掉,进行\ ...

  6. 51nod 1463 找朋友 (扫描线+线段树)

    1463 找朋友  基准时间限制:1.5 秒 空间限制:262144 KB 分值: 80 难度:5级算法题  收藏  关注 给定: 两个长度为n的数列A .B 一个有m个元素的集合K 询问Q次 每次询 ...

  7. 51nod 1494 选举拉票 (线段树+扫描线)

    1494 选举拉票  题目来源: CodeForces 基准时间限制:1 秒 空间限制:131072 KB 分值: 80 难度:5级算法题  收藏  关注 现在你要竞选一个县的县长.你去对每一个选民进 ...

  8. 51nod 1571 最近等对 | 线段树 离线

    51nod 1571 最近等对 题面 现在有一个序列 a1, a2, ..., an ,还有m个查询 lj, rj (1 ≤ lj ≤ rj ≤ n) .对于每一个查询,请找出距离最近的两个元素 ax ...

  9. 51nod 1208 窗上的星星 | 线段树 扫描线

    51nod 1208 Stars In Your Window 题面 整点上有N颗星星,每颗星星有一个亮度.用一个平行于x轴和y轴,宽为W高为H的方框去套星星.套住的所有星星的亮度之和为S(包括边框上 ...

随机推荐

  1. iOS中CocoaPods的安装及错误详解

    什么是CocoaPods CocoaPods是OS X和iOS下的一个第三类库管理工具,通过CocoaPods工具我们可以为项目添加被称为"Pods"的依赖库(这些类库必须是Coc ...

  2. 《高级软件测试》web测试实践--12月30日记录

    考完数学,我们正式开始web测试实践的作业,今天,我们主要进行了方案的选择和人员的分工.任务计划和安排如上图所示. 任务进展:完成题目选择和人员分工: 遇到问题:暂无: 下一步任务:完成软件评测.用户 ...

  3. 【基础知识】Flex-弹性布局原来如此简单!!

    简言 布局的传统解决方案是基于盒状模型,依赖 display + position + float 方式来实现,灵活性较差.2009年,W3C提出了一种新的方案-Flex,Flex是Flexible ...

  4. vue 保留两位小数 不能直接用toFixed(2) ?

    用vue做项目的时候多多少少都会遇到这个问题 刚开始我是用toFixed()这个方法来写的  效果是有的 但是控制台一直是红红的围绕着我 突然想到 vue和jquery混搭 的 问题 于是乎 看了一下 ...

  5. java截取一个字符串正数或倒数某个特定字符前后的内容

    取出正数第二个“.”后面的内容 public class TestCode { public static void main(String[] args) { String str ="2 ...

  6. WebApi 接口返回值类型详解 ( 转 )

    使用过Webapi的园友应该都知道,Webapi的接口返回值主要有四种类型 void无返回值 IHttpActionResult HttpResponseMessage 自定义类型 此篇就围绕这四块分 ...

  7. Mego开发文档 - 索引

    Mego 开发文档 Mego 快速概述 主要特性 获取Mego 使用流程 模型 查询 保存数据 入门 Mego 快速开始 创建项目 安装Nuget包 创建连接字符串 创建模型及数据上下文(添加引用) ...

  8. 获取选中的radio的value值

    html:<div id="bb"> <input  name="cc" type="radio" value=" ...

  9. python 面向对象进阶之内置方法

    一 isinstance(obj,cls)和issubclass(sub,super) 1.1,isinstance(obj,cls)检查是否obj是否是类 cls 的对象 class Foo(obj ...

  10. Web微信

    一.源代码地址: https://github.com/HuangAm/Webweixin 二.总结: 1.分析Http请求 - 请求方式:get.post等等 - URL:每个请求的url,固定部分 ...