AtCoder Grand Contest 001F Wide Swap
解法参考这位大佬的: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的更多相关文章
- 【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 ...
- AtCoder Grand Contest 009
AtCoder Grand Contest 009 A - Multiple Array 翻译 见洛谷 题解 从后往前考虑. #include<iostream> #include< ...
- AtCoder Grand Contest 007
AtCoder Grand Contest 007 A - Shik and Stone 翻译 见洛谷 题解 傻逼玩意 #include<cstdio> int n,m,tot;char ...
- AtCoder Grand Contest 006
AtCoder Grand Contest 006 吐槽 这套题要改个名字,叫神仙结论题大赛 A - Prefix and Suffix 翻译 给定两个串,求满足前缀是\(S\),后缀是\(T\),并 ...
- 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 003
AtCoder Grand Contest 003 A - Wanna go back home 翻译 告诉你一个人每天向哪个方向走,你可以自定义他每天走的距离,问它能否在最后一天结束之后回到起点. ...
- AtCoder Grand Contest 002
AtCoder Grand Contest 002 A - Range Product 翻译 告诉你\(a,b\),求\(\prod_{i=a}^b i\)是正数还是负数还是零. 题解 什么鬼玩意. ...
- AtCoder Grand Contest 019 F-yes or no
AtCoder Grand Contest 019 F-yes or no 解题思路: 考虑一个贪心策略,假设当前还有 \(x\) 道 \(\text{yes}\) 和 \(y\) 道 \(\text ...
随机推荐
- php yield关键字以及协程的实现
php的yield是在php5.5版本就出来了,而在初级php界却很少有人提起,我就说说个人对php yield的理解 Iterator接口 在php中,除了数组,对象可以被foreach遍历之外,还 ...
- 笔试算法题及解答(Python)
1.给定任意一个正整数,求比这个数大且最小的“不重复数”,“不重复数”的含义是相邻两位不相同,例如1101是重复数,而1201是不重复数 # coding:utf-8 ''' Created on 2 ...
- CNN基础一:从头开始训练CNN进行图像分类(猫狗大战为例)
本文旨在总结一次从头开始训练CNN进行图像分类的完整过程(猫狗大战为例,使用Keras框架),免得经常遗忘.流程包括: 从Kaggle下载猫狗数据集: 利用python的os.shutil库,制作训练 ...
- 21.Semaphore信号量
Semaphore是一种基于计数的信号量.它可以设定一个阈值,基于此,多个线程竞争获取许可信号,做自己的申请后归还,超过阈值后,线程申请许可信号将会被阻塞.Semaphore可以用来构建一些对象池,资 ...
- tensorflow基础重新巩固
tensorflow框架整体结构 用张量tensor表示数据:计算图graph表示任务:在会话session中执行context: 通过变量维护状态:通过feed和fetch可以任意的操作(arbit ...
- Python Socket(未编辑)
客户端 import socket 导入socket模块 client = socket.socket() 声明socket协议类型,同时生成socket连接对象 client.connect(('l ...
- nodejs npm 常用配置
npm install moduleNames : 安装 Node 模块.node安装分为全局模式和本地模式. npm install -g moduleName.npm install expres ...
- 使用nexus3.10搭建maven私有仓库
使用nexus3.10搭建maven私有仓库-----详见如下链接-- --此贴用于笔记 https://blog.csdn.net/vipbupafeng/article/details/80232 ...
- Cisco基础(五):配置静态NAT、配置端口映射、配置动态NAT、PAT配置、办公区Internet的访问
一.配置静态NAT 目标: 随着接入Internet的计算机数量的不断猛增,IP地址资源也就愈加显得捉襟见肘.事实上,除了中国教育和科研计算机网(CERNET)外,一般用户几乎申请不到整段的C类IP地 ...
- webpack 导出、导入模块(及路径)
参考:https://blog.csdn.net/xyphf/article/details/83411552 (下面的代码亲测有效) 注:导入的模块的方法,只有两种方法 import 和 requ ...