【AtCoder Grand Contest 001F】Wide Swap [线段树][拓扑]
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,我们考虑设一个p,p[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 [线段树][拓扑]的更多相关文章
- AtCoder Grand Contest 001F Wide Swap
解法参考这位大佬的:https://www.cnblogs.com/BearChild/p/7895719.html 因为原来的数组不好做于是我们想反过来数组,根据交换条件:值相邻且位置差大于等于k, ...
- AtCoder AGC001F Wide Swap (线段树、拓扑排序)
题目链接: https://atcoder.jp/contests/agc001/tasks/agc001_f 题解: 先变成排列的逆,要求\(1\)的位置最小,其次\(2\)的位置最小,依次排下去( ...
- AtCoder Grand Contest 001 C Shorten Diameter 树的直径知识
链接:http://agc001.contest.atcoder.jp/tasks/agc001_c 题解(官方): We use the following well-known fact abou ...
- AtCoder Grand Contest 011
AtCoder Grand Contest 011 upd:这篇咕了好久,前面几题是三周以前写的... AtCoder Grand Contest 011 A - Airport Bus 翻译 有\( ...
- AtCoder Grand Contest 009
AtCoder Grand Contest 009 A - Multiple Array 翻译 见洛谷 题解 从后往前考虑. #include<iostream> #include< ...
- AtCoder Grand Contest 005
AtCoder Grand Contest 005 A - STring 翻译 给定一个只包含\(ST\)的字符串,如果出现了连续的\(ST\),就把他删去,然后所有位置前移.问最后剩下的串长. 题解 ...
- AtCoder Grand Contest 004
AtCoder Grand Contest 004 A - Divide a Cuboid 翻译 给定一个\(A*B*C\)的立方体,现在要把它分成两个立方体,求出他们的最小体积差. 题解 如果有一条 ...
- AtCoder Grand Contest 014
AtCoder Grand Contest 014 A - Cookie Exchanges 有三个人,分别有\(A,B,C\)块饼干,每次每个人都会把自己的饼干分成相等的两份然后给其他两个人.当其中 ...
- AtCoder Grand Contest 012
AtCoder Grand Contest 012 A - AtCoder Group Contest 翻译 有\(3n\)个人,每一个人有一个强大值(看我的假翻译),每三个人可以分成一组,一组的强大 ...
随机推荐
- 【问底】王帅:深入PHP内核(一)——弱类型变量原理探究
来源:CSDN http://www.csdn.net/article/2014-09-15/2821685-exploring-of-the-php 作者:王帅 摘要:PHP作为一门简单而强大 ...
- js框架总结
参考地址 http://www.techweb.com.cn/network/system/2015-12-23/2245809.shtml https://www.cnblogs.com/mbail ...
- NLP & 中文分词
NLP & 中文分词 中文分词 (Word Segmentation, WS) 指的是将汉字序列切分成词序列. 中文自然语言处理系统 https://www.ltp-cloud.com/int ...
- Asp.Net Core实现文件上传
1. Asp.Net Core Mvc方式 public class UploadController : Controller { private IHostingEnvironment _host ...
- 【刷题】BZOJ 1070 [SCOI2007]修车
Description 同一时刻有N位车主带着他们的爱车来到了汽车维修中心.维修中心共有M位技术人员,不同的技术人员对不同的车进行维修所用的时间是不同的.现在需要安排这M位技术人员所维修的车及顺序,使 ...
- Vue设置不同的环境发布程序
原文地址: http://www.cnblogs.com/JimmyBright/p/7307486.html 通常应用程序上线都会经过开发环境.测试环境.生产环境三个阶段,三个环境通常会对应有三个不 ...
- bzoj1027【JSOI2007】合金
题目描述 某公司加工一种由铁.铝.锡组成的合金.他们的工作很简单.首先进口一些铁铝锡合金原材料,不同种类的原材料中铁铝锡的比重不同.然后,将每种原材料取出一定量,经过融解.混合,得到新的合金.新的合金 ...
- 【最小割/二分图最大独立集】【网络流24题】【P2774】 方格取数问题
Description 给定一个 \(n~\times~m\) 的矩阵,每个位置有一个正整数,选择一些互不相邻的数,最大化权值和 Limitation \(1~\leq~n,~m~\leq~100\) ...
- linux内核增加系统调用--Beginner's guide
Linux内核中设置了一组用于实现系统功能的子程序,称为系统调用.系统调用和普通库函数调用非常相似明知是系统调用由操作系统核心提供,运行于核心态,而普通的函数调用由函数库或用户自己提供,运行于用户态. ...
- 二、Linux学习之centOS的的setup
因为我是在VMware上安装的centOS,网络设置选择的是桥接模式,这样可以和实体机使用同样的网络,但是也使用同样的IP,因此就需要设置一下IP了,否则使用ifconfig查询ip的时候显示的是12 ...