Wide Swap

Time Limit: 50 Sec  Memory Limit: 512 MB

Description

  

Input

  

Output

  

Sample Input

  8 3
  4 5 7 8 3 1 2 6

Sample Output

  1
  2
  6
  7
  5
  3
  4
  8

HINT

  

Solution

  首先,直接做难度系数较高,假设原序列为a,我们考虑设一个pp[a_i] = i,即将题目中的权值与下标调换

  那么显然,要令a字典序最小,只要让p字典序最小即可。因为“权值小的尽量前”“前面的权值尽量小”是一个意思。

  现在操作转化为:相邻元素权值差>=k的可以换顺序。

  考虑一个暴力怎么做,显然是 i后面的所有 j 比,如果 abs(p_i - p_j) < k,则 i 和 j 的相对顺序就确定了, 连一条 p_i -> p_j 的边。

  连边之后跑一边拓扑即可。

  显然复杂度在于连边,因为这样暴力会有很多无用边。比如A->B, B->C, A->C,这条A->C显然无用

  我们考虑如何删掉 A->C 这种边。

  倒着加入,显然 p_i 连向 (p_i-k, p_i)∪(p_i, p_i+k)。我们只需要分别连向两个区间中下标最小的那一个即可。用线段树维护一下区间最小值

Code

 #include<iostream>
#include<string>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<queue>
using namespace std;
typedef long long s64; #define next nxt
const int ONE = ;
const int INF = ; int get()
{
int res = , Q = ; char c;
while( (c = getchar()) < || c > )
if(c == '-') Q = -;
if(Q) res = c - ;
while( (c = getchar()) >= && c <= )
res = res * + c - ;
return res * Q;
} int n, k;
int A[ONE], p[ONE];
int next[ONE], first[ONE], go[ONE], Input[ONE], tot;
priority_queue <int, vector <int>, greater <int> > q; int res = INF;
namespace Seg
{
struct power {int val;} Node[ONE * ];
void Build(int i, int l, int r)
{
Node[i].val = INF;
if(l == r) return;
int mid = l + r >> ;
Build(i << , l, mid), Build(i << | , mid + , r);
} void Update(int i, int l, int r, int L, int x)
{
if(L <= l && r <= L)
{
Node[i].val = x;
return;
}
int mid = l + r >> ;
if(L <= mid) Update(i << , l, mid, L, x);
else Update(i << | , mid + , r, L, x);
Node[i].val = min(Node[i << ].val, Node[i << | ].val);
} void Query(int i, int l, int r, int L, int R)
{
if(L > R) return;
if(L <= l && r <= R)
{
res = min(res, Node[i].val);
return;
}
int mid = l + r >> ;
if(L <= mid) Query(i << , l, mid, L, R);
if(mid + <= R) Query(i << | , mid + , r, L, R);
}
} void Add(int u, int v)
{
Input[v]++, next[++tot] = first[u], first[u] = tot, go[tot] = v;
} void Deal()
{
int now = ;
for(int i = ; i <= n; i++)
if(!Input[i]) q.push(i);
while(!q.empty())
{
int u = q.top(); q.pop();
A[u] = ++now;
for(int e = first[u]; e; e = next[e])
{
int v = go[e];
if(--Input[v] == ) q.push(v);
}
}
for(int i = ; i <= n; i++) printf("%d\n", A[i]);
} int main()
{
n = get(), k = get();
for(int i = ; i <= n; i++) p[get()] = i; Seg::Build(, , n);
for(int i = n; i >= ; i--)
{
res = INF, Seg::Query(, , n, p[i] + , min(p[i] + k - , n));
if(res != INF) Add(p[i], p[res]); res = INF, Seg::Query(, , n, max(, p[i] - k + ), p[i] - );
if(res != INF) Add(p[i], p[res]); Seg::Update(, , n, p[i], i);
} Deal();
}

【AtCoder Grand Contest 001F】Wide Swap [线段树][拓扑]的更多相关文章

  1. AtCoder Grand Contest 001F Wide Swap

    解法参考这位大佬的:https://www.cnblogs.com/BearChild/p/7895719.html 因为原来的数组不好做于是我们想反过来数组,根据交换条件:值相邻且位置差大于等于k, ...

  2. AtCoder AGC001F Wide Swap (线段树、拓扑排序)

    题目链接: https://atcoder.jp/contests/agc001/tasks/agc001_f 题解: 先变成排列的逆,要求\(1\)的位置最小,其次\(2\)的位置最小,依次排下去( ...

  3. AtCoder Grand Contest 001 C Shorten Diameter 树的直径知识

    链接:http://agc001.contest.atcoder.jp/tasks/agc001_c 题解(官方): We use the following well-known fact abou ...

  4. AtCoder Grand Contest 011

    AtCoder Grand Contest 011 upd:这篇咕了好久,前面几题是三周以前写的... AtCoder Grand Contest 011 A - Airport Bus 翻译 有\( ...

  5. AtCoder Grand Contest 009

    AtCoder Grand Contest 009 A - Multiple Array 翻译 见洛谷 题解 从后往前考虑. #include<iostream> #include< ...

  6. AtCoder Grand Contest 005

    AtCoder Grand Contest 005 A - STring 翻译 给定一个只包含\(ST\)的字符串,如果出现了连续的\(ST\),就把他删去,然后所有位置前移.问最后剩下的串长. 题解 ...

  7. AtCoder Grand Contest 004

    AtCoder Grand Contest 004 A - Divide a Cuboid 翻译 给定一个\(A*B*C\)的立方体,现在要把它分成两个立方体,求出他们的最小体积差. 题解 如果有一条 ...

  8. AtCoder Grand Contest 014

    AtCoder Grand Contest 014 A - Cookie Exchanges 有三个人,分别有\(A,B,C\)块饼干,每次每个人都会把自己的饼干分成相等的两份然后给其他两个人.当其中 ...

  9. AtCoder Grand Contest 012

    AtCoder Grand Contest 012 A - AtCoder Group Contest 翻译 有\(3n\)个人,每一个人有一个强大值(看我的假翻译),每三个人可以分成一组,一组的强大 ...

随机推荐

  1. vue 过渡效果

    Vue中提供了`<transition>`和`<transition-group>`来为元素增加过渡动画.文档写的很清楚,但是实际使用起来还是费了一番功夫.这里做一个简单的记录 ...

  2. 结对编程:四则运算。组员:闫浩楠 杨钰宁 开发语言:C语言

    需求分析:1.能够自动出题并给出答案 2.包含“+,—,*,/,()” 的四则运算. 3.显示题目的答案 结构设计:1.自动出题用随机数生成语句实现:包括随机生成数字.运算符号和题目长度 2.用变量约 ...

  3. #Leetcode# 707. Design Linked List

    https://leetcode.com/problems/design-linked-list/ Design your implementation of the linked list. You ...

  4. macOS & SVN

    macOS & SVN mac 下已经自带了svn环境; 使用 svn –version 查看版本号 安装方法: 已安装 XCode,只需要在 code > Preferences &g ...

  5. 计算机网络【3】—— IP地址分类与子网划分

    一.IP地址分类

  6. DAY2-Flask项目

    回顾: 1.安装pipenv虚拟运行环境,隔离项目 (启动:pipenv shell) 2.安装flask(pipenv install shell),查看项目依赖(pipenv graph) 3.查 ...

  7. PowerDesigner在生成SQL时报错Generation aborted due to errors detected during the verification of the mod

    一.本章节要用到  ODBC连接数据库直接创建表,请先创建连接库的ODBC 请参考  新建  http://www.cnblogs.com/wdw31210/p/7580286.html 二.生成 去 ...

  8. 【刷题】LOJ 2480 「CEOI2017」One-Way Streets

    题目描述 给定一张 \(n\) 个点 \(m\) 条边的无向图,现在想要把这张图定向. 有 \(p\) 个限制条件,每个条件形如 \((xi,yi)\) ,表示在新的有向图当中,\(x_i\) 要能够 ...

  9. 【BZOJ3622】已经没有什么好害怕的了(动态规划,容斥)

    [BZOJ3622]已经没有什么好害怕的了(动态规划,容斥) 题面 BZOJ 题解 很明显的,这类问题是要从至少变成恰好的过程,直接容斥即可. 首先我们要求的是(糖果>药片)=(药片>糖果 ...

  10. 【BZOJ3293】分金币(贪心)

    [BZOJ3293]分金币(贪心) 题面 BZOJ 洛谷 题解 和上一题一样啊. #include<cstdio> #include<cmath> #include<al ...