P15652 [省选联考 2026] 排列游戏 / perm
纯靠对
以下
有一个大概的思路就是,先找到数
假设当前区间覆盖了
判断
出于需求,只要求出所有包含数
从
代码中部分细节进行了简化。
:::success[排列游戏 - perm.cpp]
#include"perm.h"
#include<bits/stdc++.h>
using namespace std;
const int maxn=30005;
int dpl[maxn],dpr[maxn],pos[maxn],sta[maxn];
int c,t;
void init(int C,int T){
c=C,t=T;
}
vector<int> perm(int n){
int top=0;
pos[0]=0;
dpr[n-1]=n;
for(int i=n-2;i>=0;i--){
dpr[i]=query(0,i);
if(dpr[i]==0){pos[0]=i+1;break;}
}
dpl[0]=n;
for(int i=1;i<=pos[0];i++){
dpl[i]=query(i,n-1);
}
int pl=pos[0],pr=pos[0],now=0;
while(pl>0 or pr<n-1){
++now;
if(dpr[pr]>now){
pos[now]=pl;
while(dpl[pos[now]]<=now) pos[now]--;
for(int i=pos[now]+1;i<pl;i++) sta[++top]=i;
pl=pos[now];
}
else{ // dpl[pl]>now
pos[now]=pr;
while(dpr[pos[now]]<=now) pos[now]++;
for(int i=pos[now]-1;i>pr;i--) sta[++top]=i;
pr=pos[now];
}
int val=min(dpr[pr],dpl[pl])-1;
while(now<val) pos[++now]=sta[top--];
}
vector<int>res;
for(int i=0;i<n;i++) res.push_back(0);
for(int i=0;i<n;i++) res[pos[i]]=i;
return res;
}
:::