解法参考这位大佬的:https://www.cnblogs.com/BearChild/p/7895719.html

因为原来的数组不好做于是我们想反过来数组,根据交换条件:值相邻且位置差大于等于k,那么在变换后的数组就变成了位置相邻且差值大于等于k。这样的话变换操作变成了,相邻的大于等于k的值临近交换,于是我们注意到因为现在只能临近交换的原因,两个差值小于k的数他们的相对位置不可能发生改变。那么问题就变成了,在只有一些相对位置限制条件下,无限制的可以随意交换位置,求这个数组的最小字典序(原数组字典序最小也是现在数组字典序最小)。那么我们容易想到拓扑排序。

但是如果每个点都想后面差值小于k的点连边的话,这个图会变得十分巨大,时间无法承受。于是我们必循得考虑优化建图:我们注意到像a->b,b->c,a->c这种建图,a->c这条边是不必要的。于是我们想办法避免掉这种无意义的边,所以对于某个点,我们让它向后面的所有限制(即差值小于k)中只向最小的那一个点连边,那么用线段树维护这样的信息,这样就达到优化建图的目的。

这样只向最小的连边为什么是对的呢?借用上面大佬的一句话:倒着加入,显然 p_i 连向 (p_i-k, p_i)∪(p_i, p_i+k)。我们只需要分别连向两个区间中下标最小的那一个即可。

#include<bits/stdc++.h>
using namespace std;
const int N=5e5+;
const int INF=0x3f3f3f3f;
int n,k,tot,a[N],pos[N],deg[N],ans[N];
set<int> L,R;
vector<int> G[N]; priority_queue<int> q;
void toposort() {
for (int i=;i<=n;i++)
if (deg[i]==) q.push(-i);
while (!q.empty()) {
int x=-q.top(); q.pop();
a[++tot]=x;
for (int i=;i<G[x].size();i++) {
int y=G[x][i];
if (--deg[y]==) q.push(-y);
}
}
} int Min[N<<];
void build(int rt,int l,int r) {
Min[rt]=INF;
if (l==r) return;
int mid=l+r>>;
build(rt<<,l,mid); build(rt<<|,mid+,r);
} void update(int rt,int l,int r,int q,int v) {
if (l==r) { Min[rt]=min(Min[rt],v); return; }
int mid=l+r>>;
if (q<=mid) update(rt<<,l,mid,q,v);
if (q>mid) update(rt<<|,mid+,r,q,v);
Min[rt]=min(Min[rt<<],Min[rt<<|]);
} int query(int rt,int l,int r,int ql,int qr) {
if (ql<=l && r<=qr) return Min[rt];
int mid=l+r>>;
int ret=INF;
if (ql<=mid) ret=min(ret,query(rt<<,l,mid,ql,qr));
if (qr>mid) ret=min(ret,query(rt<<|,mid+,r,ql,qr));
return ret;
} int main()
{
cin>>n>>k;
for (int i=;i<=n;i++) scanf("%d",&a[i]);
for (int i=;i<=n;i++) pos[a[i]]=i; build(,,n);
for (int i=n;i;i--) {
int t1=query(,,n,max(,pos[i]-k+),pos[i]);
if (t1<=n) G[pos[i]].push_back(pos[t1]),deg[pos[t1]]++;
int t2=query(,,n,pos[i],min(n,pos[i]+k-));
if (t2<=n) G[pos[i]].push_back(pos[t2]),deg[pos[t2]]++;
update(,,n,pos[i],i);
} toposort();
for (int i=;i<=n;i++) ans[a[i]]=i; //最后记得把答案反过来
for (int i=;i<=n;i++) printf("%d\n",ans[i]);
return ;
}

AtCoder Grand Contest 001F Wide Swap的更多相关文章

  1. 【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 ...

  2. AtCoder Grand Contest 009

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

  3. AtCoder Grand Contest 007

    AtCoder Grand Contest 007 A - Shik and Stone 翻译 见洛谷 题解 傻逼玩意 #include<cstdio> int n,m,tot;char ...

  4. AtCoder Grand Contest 006

    AtCoder Grand Contest 006 吐槽 这套题要改个名字,叫神仙结论题大赛 A - Prefix and Suffix 翻译 给定两个串,求满足前缀是\(S\),后缀是\(T\),并 ...

  5. AtCoder Grand Contest 005

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

  6. AtCoder Grand Contest 004

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

  7. AtCoder Grand Contest 003

    AtCoder Grand Contest 003 A - Wanna go back home 翻译 告诉你一个人每天向哪个方向走,你可以自定义他每天走的距离,问它能否在最后一天结束之后回到起点. ...

  8. AtCoder Grand Contest 002

    AtCoder Grand Contest 002 A - Range Product 翻译 告诉你\(a,b\),求\(\prod_{i=a}^b i\)是正数还是负数还是零. 题解 什么鬼玩意. ...

  9. AtCoder Grand Contest 019 F-yes or no

    AtCoder Grand Contest 019 F-yes or no 解题思路: 考虑一个贪心策略,假设当前还有 \(x\) 道 \(\text{yes}\) 和 \(y\) 道 \(\text ...

随机推荐

  1. shell函数与变量

  2. 五、通过密码访问API

    通过密码访问API 一.客户端 图: 客户端请求代码: static void Main(string[] args) { Console.WriteLine("确定三个项目都已经启动&qu ...

  3. 力扣 ——Linked List Cycle II(环形链表 II) python实现

    题目描述: 中文: 给定一个链表,返回链表开始入环的第一个节点. 如果链表无环,则返回 null. 为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始). ...

  4. C# IOC DI 学习

    之前一直不理解IOC DI,今天使劲研究了下,感觉朦朦胧胧有点感觉了,网上的这篇文章对我的有很大的启发 http://www.cnblogs.com/jin-yuan/p/3823559.html 我 ...

  5. 职责链模式ChainOfResponsibility

    原创转载请注明出处:https://www.cnblogs.com/agilestyle/p/11407114.html  1.定义 使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合 ...

  6. c++11 委派构造函数

    委派构造函数可以减少构造函数的书写量: class Info { public: Info() : type(), name('a') { InitRest(); } Info(int i) : ty ...

  7. nucleus plus学习总结(后续)

    前言:     刚刚抽筋点了保存发布,结果要审核,那就分开写个续好了. 内容: signal     信号是异步通知task的一种机制,HISR是不可以接收信号的,但是可以发送信号.     TCB中 ...

  8. mybatis plus generator工具集成(一)

    参数配置文档 配置分两步 1.添加依赖 <dependency> <groupId>com.baomidou</groupId> <artifactId> ...

  9. appium 链接真机

    1. 安装驱动 说明:如果驱动装不上,可以使用第三方的工具去安装.(一般来说还是用第三方) 这里推荐锤子科技的HandShaker, 地址:http://www.smartisan.com/apps/ ...

  10. HTML-参考手册: HTML 全局属性

    ylbtech-HTML-参考手册: HTML 全局属性 1.返回顶部 1. HTML 全局属性 New : HTML5 新属性. 属性 描述 accesskey 设置访问元素的键盘快捷键. clas ...