JZOJ5405. 【NOIP2017提高A组模拟10.10】Permutation
来源:互联网 发布:jquery ajax post json 编辑:程序博客网 时间:2024/06/04 17:52
Description
你有一个长度为n 的排列P 与一个正整数K
你可以进行如下操作若干次使得排列的字典序尽量小
对于两个满足|i-j|>=K 且|Pi-Pj| = 1 的下标i 与j,交换Pi 与Pj
Input
第一行包括两个正整数n 与K
第二行包括n 个正整数,第i 个正整数表示Pi
Output
输出一个新排列表示答案
输出共n 行,第i 行表示Pi
Sample Input
8 3
4 5 7 8 3 1 2 6
Sample Output
1
2
6
7
5
3
4
8
Data Constraint
对于前20% 的数据满足n <= 6
对于前50% 的数据满足n <= 2000
对于100% 的数据满足n <= 500000
题解
因为有|Pi-Pj| = 1,意思就是只有P的值是相邻的才能交换。
我们构造一个新的序列:
那么在q序列中,可以交换的只有相邻的两个,
即
而且,
如果对于1..i中,都满足
如果,在i的前面的某个位置j,不满足
那么,i最多只能被交换到j的位置。
这就说明了它们的位置的相对顺序是不会改变的。
根据这个相对顺序来连边,
然后跑一边拓扑序,注意一下最小值就可以了。
code
#include<queue>#include<cstdio>#include<iostream>#include<algorithm>#include <cstring>#include <string.h>#include <cmath>#include <math.h>#define ll long long#define N 500003#define db double#define P putchar#define G getchar#define mo 998244353using namespace std;char ch;void read(int &n){ n=0; ch=G(); while((ch<'0' || ch>'9') && ch!='-')ch=G(); ll w=1; if(ch=='-')w=-1,ch=G(); while('0'<=ch && ch<='9')n=(n<<3)+(n<<1)+ch-'0',ch=G(); n*=w;}db max(db a,db b){return a>b?a:b;}db min(db a,db b){return a<b?a:b;}ll abs(ll x){return x<0?-x:x;}ll sqr(ll x){return x*x;}void write(ll x){if(x>9) write(x/10);P(x%10+'0');}struct node{int x;}t;priority_queue <node> d;bool operator <(node a,node b){ return a.x<b.x;}int n,k,ans[N],x,p[N],q[N];int nxt[N*2],f[N],to[N*2],b[N],tot;int tr[N*4],opl,opr,opx,ops;void work(int x,int l,int r){ if(opl<=l && r<=opr) { if(opx==1)ops=min(ops,tr[x]); if(opx==2)tr[x]=ops; return; } int m=(l+r)>>1; if(opl<=m)work(x+x,l,m); if(m<opr)work(x+x+1,m+1,r); tr[x]=min(tr[x+x],tr[x+x+1]);}void ins(int x,int y){ nxt[++tot]=b[x]; to[tot]=y; b[x]=tot; f[y]++;}int main(){ freopen("permutation.in","r",stdin); freopen("permutation.out","w",stdout); read(n);read(k);memset(tr,127,sizeof(tr)); for(int i=1;i<=n;i++) read(p[i]),q[p[i]]=i; for(int i=n;i;i--) { opl=q[i]-k+1;opr=q[i];opx=1;ops=n+1; work(1,1,n); if(ops<n+1)ins(q[ops],q[i]); opl=q[i];opr=q[i]+k-1;opx=1;ops=n+1; work(1,1,n); if(ops<n+1)ins(q[ops],q[i]); opl=q[i];opr=q[i];opx=2;ops=i; work(1,1,n); } for(int i=1;i<=n;i++) if(f[i]==0)t.x=i,d.push(t); for(int i=n;i;i--) { t=d.top();d.pop();x=t.x;p[i]=x; for(int i=b[x];i;i=nxt[i]) { f[to[i]]--; if(f[to[i]]==0)t.x=to[i],d.push(t); } } for(int i=1;i<=n;i++) q[p[i]]=i; for(int i=1;i<=n;i++) write(q[i]),P('\n');}
阅读全文
0 0
- [JZOJ5405]【NOIP2017提高A组模拟10.10】Permutation
- JZOJ5405. 【NOIP2017提高A组模拟10.10】Permutation
- 【jzoj5405】【NOIP2017提高A组模拟10.10】【Permutation】
- 【NOIP2017提高A组模拟10.10】Permutation
- 【JZOJ 5405】【NOIP2017提高A组模拟10.10】Permutation
- JZOJ 5405.【NOIP2017提高A组模拟10.10】Permutation
- JZOJ 5405. 【NOIP2017提高A组模拟10.10】Permutation
- 【NOIP2017提高A组模拟10.10】总结
- 【NOIP2017提高A组模拟10.10】Graph
- JZOJ 5406. 【NOIP2017提高A组模拟10.10】Tree
- JZOJ 5404. 【NOIP2017提高A组模拟10.10】Graph
- JZOJ 5404. 【NOIP2017提高A组模拟10.10】Graph
- [jzoj5406]【NOIP2017提高A组模拟10.10】Tree
- 5404. 【NOIP2017提高A组模拟10.10】Graph
- A【NOIP2017提高组模拟12.18】
- 【JZOJ4928】【NOIP2017提高组模拟12.18】A
- 【NOIP2017提高组模拟12.18】A
- 【JZOJ4928】【NOIP2017提高组模拟12.18】A
- 你可能不知道的 5 个强大的 HTML5 API
- css 布局 两列布局与三列布局
- 浅析redux-saga实现原理
- 精通多线程(一)-死锁
- 初赛中の一些知识点
- JZOJ5405. 【NOIP2017提高A组模拟10.10】Permutation
- Nginx + CGI/FastCGI + C/Cpp
- Hello World
- MDK在链接时提示空间不够(No space in execution regions with .ANY selector... )解决方案
- Laravel-学习笔记-多用户表登陆分析与实现(Authentication)
- oracle中执行execute的时候报异常ORA-01031的解决办法
- Java写的众数问题
- 让你的程序有管理员权限
- 【JSON】简介