Atcoder 题面传送门 & 洛谷题面传送门

咦?鸽子 tzc 来补题解了?奇迹奇迹(

首先考虑什么样的排列可以得到。我们考虑 \(p\) 的逆排列 \(q\),那么每次操作的过程从逆排列的角度思考,就可视作每次在逆排列中交换两个相邻,且元素值之差 \(\ge k\) 的元素。注意到对于两个元素 \(x,y\),如果 \(|x-y|<k\),那么我们肯定永远无法交换它们,它们的相对位置顺序也永远无法改变,因为要改变它们的相对顺序必须交换它们。而一对 \(|q_i-q_j|<k,i<j\) 的 \((i,j)\) 恰好对应一对 \(p_i<p_j,|i-j|<k\) 的 \((i,j)\)。因此对于相距 \(<k\) 的位置,它们的相对大小顺序不能发生变化。而我们能够证明,如果两个排列 \(p,p'\),满足它们相距 \(<k\) 的位置上的元素相对位置大小不变,那么它们之间就能够互相转化,证明我也不太会,一个感性地想法是,我们记排列 \(q\) 满足 \(p\circ q=p'\),那么我们每次总能交换两个数,使得 \(q\) 逆序对大小减一,因此它们能够互相转化。

我们考虑对于 \(|i-j|<k\),如果 \(p_i<p_j\) 则连一条 \(i\to j\) 的边,否则连一条 \(j\to i\) 的边,那么不考虑复杂度的问题,我们的目标就是给每个点赋上一个标号 \(r_i\),使得对于所有有向边 \(u\to v\),都有 \(r_u<r_v\),并且 \(r\) 的字典序尽可能小。这是一个经典问题,考虑这样的过程,我们建反图然后拓扑排序,每次取出编号最大的点然后在上面填 \(n,n-1,\cdots\) 以此类推,类似的题有这个(它是道 Ag 的题但代码异常短)。但是暴力建图复杂度是 \(nk\) 的,无法通过。不过注意到此题建图方式很特殊,\(n^2\) 建边+特殊建图方式 \(=n\log n\)(暴论),注意到一个点 \(x\) 度为 \(0\),当且仅当 \(p_x\) 为 \([x-k+1,x+k-1]\) 的最大值,因此我们考虑用线段树维护这个过程,先一遍扫过去将所有度为 \(0\) 的点压入优先队列,然后每次取出一个点 \(x\) 时,就将 \(p_x\) 改为 \(-\infty\),然后松弛与其相连的点即可。不难发现每次松弛只有 \([x-k+1,x-1]\) 中最大值的位置和 \([x+1,x+k-1]\) 最大值的位置是有用的,只用松弛这两个点即可。

时间复杂度 \(n\log n\)。

const int MAXN=5e5;
int n,m,p[MAXN+5],res[MAXN+5];
struct node{int l,r;pii mx;} s[MAXN*4+5];
void pushup(int k){s[k].mx=max(s[k<<1].mx,s[k<<1|1].mx);}
void build(int k,int l,int r){
s[k].l=l;s[k].r=r;if(l==r) return s[k].mx=mp(p[l],l),void();
int mid=l+r>>1;build(k<<1,l,mid);build(k<<1|1,mid+1,r);
pushup(k);
}
void modify(int k,int p,pii v){
if(s[k].l==s[k].r) return s[k].mx=v,void();
int mid=s[k].l+s[k].r>>1;
(p<=mid)?modify(k<<1,p,v):modify(k<<1|1,p,v);
pushup(k);
}
pii query(int k,int l,int r){
if(l<=s[k].l&&s[k].r<=r) return s[k].mx;
int mid=s[k].l+s[k].r>>1;
if(r<=mid) return query(k<<1,l,r);
else if(l>mid) return query(k<<1|1,l,r);
else return max(query(k<<1,l,mid),query(k<<1|1,mid+1,r));
}
priority_queue<int> q;
bool inq[MAXN+5];
void check(int x){
if(!x||inq[x]) return;
if(x==query(1,max(x-m,1),min(x+m,n)).se)
q.push(x),inq[x]=1;
}
int main(){
scanf("%d%d",&n,&m);--m;
for(int i=1;i<=n;i++) scanf("%d",&p[i]);
build(1,1,n);int c=n;
for(int i=1;i<=n;i++) check(i);
while(!q.empty()){
int x=q.top();q.pop();res[x]=c--;
// printf("%d\n",x);
modify(1,x,mp(-INF,0));
check(query(1,max(x-m,1),x).se);
check(query(1,x,min(x+m,n)).se);
} for(int i=1;i<=n;i++) printf("%d\n",res[i]);
return 0;
}

Atcoder Grand Contest 001 F - 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. JZOJ5405 & AtCoder Grand Contest 001 F. Permutation

    题目大意 给出一个长度为\(n\)的排列\(P\)与一个正整数\(k\). 你需要进行如下操作任意次, 使得排列\(P\)的字典序尽量小. 对于两个满足\(|i-j|>=k\) 且\(|P_i- ...

  3. AtCoder Grand Contest 001 D - Arrays and Palindrome

    题目传送门:https://agc001.contest.atcoder.jp/tasks/agc001_d 题目大意: 现要求你构造两个序列\(a,b\),满足: \(a\)序列中数字总和为\(N\ ...

  4. AtCoder Grand Contest 003 F - Fraction of Fractal

    题目传送门:https://agc003.contest.atcoder.jp/tasks/agc003_f 题目大意: 给定一个\(H×W\)的黑白网格,保证黑格四连通且至少有一个黑格 定义分形如下 ...

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

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

  6. [Atcoder Grand Contest 001] Tutorial

    Link: AGC001 传送门 A: …… #include <bits/stdc++.h> using namespace std; ; ]; int main() { scanf(& ...

  7. AtCoder Grand Contest 002 F:Leftmost Ball

    题目传送门:https://agc002.contest.atcoder.jp/tasks/agc002_f 题目翻译 你有\(n*k\)个球,这些球一共有\(n\)种颜色,每种颜色有\(k\)个,然 ...

  8. AtCoder Grand Contest 017 F - Zigzag

    题目传送门:https://agc017.contest.atcoder.jp/tasks/agc017_f 题目大意: 找出\(m\)个长度为\(n\)的二进制数,定义两个二进制数的大小关系如下:若 ...

  9. AtCoder Grand Contest 011 F - Train Service Planning

    题目传送门:https://agc011.contest.atcoder.jp/tasks/agc011_f 题目大意: 现有一条铁路,铁路分为\(1\sim n\)个区间和\(0\sim n\)个站 ...

随机推荐

  1. 实现服务器和客户端数据交互,Java Socket有妙招

    摘要:在Java SDK中,对于Socket原生提供了支持,它分为ServerSocket和Socket. 本文分享自华为云社区<Java Socket 如何实现服务器和客户端数据交互>, ...

  2. 生产环境全链路压测平台 Takin

    什么是Takin? Takin是基于Java的开源系统,可以在无业务代码侵入的情况下,嵌入到各个应用程序节点,实现生产环境的全链路性能测试,适用于复杂的微服务架构系统. Takin核心原理图 Taki ...

  3. xshell几款绝佳配色方案

    NO.1 [mycolor] text(bold)=e9e9e9 magenta(bold)=ff00ff text=00ff80 white(bold)=fdf6e3 green=80ff00 re ...

  4. OO第二单元——多线程(电梯)

    OO第二单元--多线程(电梯) 综述 第二单元的三次联系作业都写电梯,要求逐步提高,对于多线程的掌握也进一步加深.本次作业全部都给出了输入输出文件,也就避免了正则表达式判断输入输出是否合法的问题. 第 ...

  5. 2021.8.3考试总结[NOIP模拟29]

    T1 最长不下降子序列 数据范围$1e18$很不妙,但模数$d$只有$150$,考虑从这里突破. 计算的式子是个二次函数,结果只与上一个值有关,而模$d$情况下值最多只有$150$个,就证明序列会出现 ...

  6. [BZOJ3307] 雨天的尾巴-----------------线段树进阶

    虽然是个板子,但用到了差分思想. Description N个点,形成一个树状结构.有M次发放,每次选择两个点x,y对于x到y的路径上(含x,y)每个点发一袋Z类型的物品.完成所有发放后,每个点存放最 ...

  7. segyio库的使用

    最近在使用segyio库读取segy文件的时候默认读取总是出现问题,经过分析发现是我们通常所用的segy格式与本库的默认格式略有不同,修改参数就可以读取: 1) with segyio.open(fi ...

  8. Machine learning(1-Introduction)

    1.What is machine learning Field of study that gives computers the ability to learn without being ex ...

  9. 『学了就忘』Linux基础 — 7、补充:安装Linxu系统时设置硬盘挂载说明

    目录 (1)新建一个/home分区 (2)再创建一个/boot分区. (3)创建一个swap分区 (4)最后剩余的空间全部分给根目录 (5)总结 上一篇在VMwar虚拟机中安装Linux操作系统中ht ...

  10. 从零开始 DIY 智能家居 - 基于 ESP32 的智能语音合成播报模块

    目录 前言 硬件选择 代码解析 获取代码 设备控制命令: 设备和协议初始化流程: 配置设备信息 回调函数注册 语音播报与设置流程 总结 前言 这里这么多设备,突然发现我做的好像都是传感器之类的居多好像 ...