arc165F
arc165F
题目描述:
给定
每一次操作可以交换相邻的两个数,询问最少多少次操作可以使得序列
在保证为最小操作次数的前提下,输出所有可以得到序列中字典序最小的那一个。
对于
题目分析:
先不考虑字典序最小,考虑操作数最小怎么得到。
若只有两个数,那么可能出现的情况只有两种:
显然第一个变成
扩展一下,对于一个数
那么对于任意的
发现边的个数是
如果只有一维,即只有
但是现在有两维,分治把第一维给去掉,这样就可以
代码:
点击查看代码
const int INF=1e9+7;
const int N=4e5+7;
int pos1[N],pos2[N],deg[N*50];
int n,a[N],L[N],R[N],tot,b[N];
vector<int> G[N*50];
bool cmp(int a,int b){
return L[a]<L[b];
}
void add(int u,int v){
G[u].p_b(v);
deg[v]++;
}
void solve(int l,int r){
if (l==r) return;
int mid=(l+r)>>1;
solve(l,mid);solve(mid+1,r);
int posl=l,posr=mid+1;
for (int i=l;i<=mid;i++){
++tot;pos1[i]=tot;add(a[i],pos1[i]);
if (i!=l) add(pos1[i-1],pos1[i]);
}
for (int i=r;i>mid;i--){
++tot;pos2[i]=tot;add(pos2[i],a[i]);
if (i!=r) add(pos2[i],pos2[i+1]);
}
int cnt=l-1;
while(posl<=mid&&posr<=r){
if (R[a[posl]]<R[a[posr]]) add(pos1[posl],pos2[posr]),b[++cnt]=a[posl],posl++;
else b[++cnt]=a[posr],posr++;
}
while(posl<=mid) b[++cnt]=a[posl],posl++;
while(posr<=r) add(pos1[mid],pos2[posr]),b[++cnt]=a[posr],posr++;
for (int i=l;i<=r;i++) a[i]=b[i];
}
void topo(){
queue<int> q1;
priority_queue<int> q2;
for (int i=1;i<=tot;i++){
if (!deg[i]){
if (i<=n) q2.push(-i);
else q1.push(i);
}
}
while((!q1.empty())||(!q2.empty())){
int u;
if (q1.empty()) u=-q2.top(),q2.pop();
else u=q1.front(),q1.pop();
if (u<=n) printf("%d %d ",u,u);
for (auto v:G[u]){
deg[v]--;
if (!deg[v]){
if (v<=n) q2.push(-v);
else q1.push(v);
}
}
}
}
signed main(){
scanf("%d",&n);
for (int i=1;i<=2*n;i++){
int x=read();
if (!L[x]) L[x]=i;
else R[x]=i;
}
for (int i=1;i<=n;i++) a[i]=i;
sort(a+1,a+n+1,cmp);
tot=n;
solve(1,n);
topo();
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话