【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学习心得1
php是动态网站开发的优秀语言,在学习的时候万万不能冒进.在系统的学习前,我认为不应该只是追求实现某种效果,因为即使你复制他人的代码调试成功,实现了你所期望的效果,你也不了解其中的原理,这样你很难利用 ...
- JDBC的基础接口及其用法
JDBC基础 所谓JDBC即是:Java DataBase Connectivity,java与数据库的连接.是一些用来执行SQL语句的Java API. 我们进行JDBC的编程,主要常用的几个概念: ...
- Android Studio系列教程
Android Studio系列教程 Android Studio系列教程一 —- 下载与安装 Android Studio系列教程二 —- 基本设置与运行 Android Studio系列教程三 — ...
- HDU 6166 Senior Pan(二进制分组+最短路)
题意 给出一个\(n\)个点\(m\)条边的有向图\((n,m<=100000)\),从中选择\(k\)个点\((k<=n)\),问这k个点两两之间的最短路最小值是多少? 思路 直接的想法 ...
- Theme Section HDU - 4763(些许暴力)
题意: 求出最长公共前后缀 不能重叠 而且 这个前后缀 在串的中间也要出现一次 解析: 再明确一次next数组的意思:完全匹配的最长前后缀长度 求一遍next 然后暴力枚举就好了 #include ...
- ibatis解决sql注入问题
原文: http://blog.csdn.net/scorpio3k/article/details/7610973 对于ibaits参数引用可以使用#和$两种写法,其中#写法会采用预编译方式,将转义 ...
- Spring点滴六:Spring中定义bean的继承
在基于XML配置元数据中,bean标签可以包含很多配置信息,可以包含构造函数的参数,属性值以及其他一些初始化方法.子bean的定义可以继承父bean定义元数据,子bean定义可以根据需要重写父bean ...
- 跟踪分析Linux内核的启动过程--20135334赵阳林
解决ubuntu下make menuconfig错误问题 http://blog.sina.com.cn/s/blog_726684020100r1oo.html 安装好相关的软件之后,键入make ...
- maven使用内嵌tomcat7
在web项目的pom.xml中添加如下: <build> <plugins> <plugin> <groupId>org.apache.tomcat.m ...
- 【题解】Willem, Chtholly and Seniorious Codeforces 896C ODT
Prelude ODT这个东西真是太好用了,以后写暴力骗分可以用,写在这里mark一下. 题目链接:ヽ(✿゚▽゚)ノ Solution 先把原题解贴在这里:(ノ*・ω・)ノ 简单地说,因为数据是全部随 ...