给你一个1~n的排列p,n是偶数,每次从中任选一对相邻的数出来,插到排列q的开头,如此循环,问你所能得到的字典序最小的排列q。

我们先确定q开头的两个数q1,q2,q1一定是p的奇数位的最小的数,而q2一定是q1后面最小的偶数位的数,这很显然。

然后记q1,q2在p中的位置分别是L,R,把p分成三段[1,L],[L+1,R-1],[R+1,n],递归处理,当前区间[l,r],每次取的一对的左端点L必然是与当前区间左端点l奇偶性相同的最小的数,而R必然是L右侧与当前区间左端点l奇偶性不同的最小的数。

可以对奇数位和偶数位分别维护一个线段树。

重点是输出答案,我们从前往后构造q,我们发现,所有的数对形成了一个树形结构,比如说[l,r],通过之前我们说的过程,取得数对L,R,则[L,R]之间的数对都必须在L,R输出之后才能输出,我们把这些数对记作[L,R]的子树,递归把树建出来。

然后对我们构造出的这棵树,一开始把所有根的儿子加入堆,我们每次取当前堆里数对左侧的数最小的,输出,然后把它的儿子都加进堆,因为它的所有儿子都“解除了封锁”。如此直到堆空即可。

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
priority_queue<int,vector<int>,greater<int> >Heap;
#define lson rt<<1,l,m
#define rson rt<<1|1,m+1,r
int v[200005],first[200005],nex[200005],e;
void AddEdge(int U,int V){v[++e]=V;nex[e]=first[U];first[U]=e;
}
int a[200005],cnt,ma[200005],pai[200005];
int minv[2][100005<<4],n,pos[200005];
void update(int o,int p,int v,int rt,int l,int r)
{if(l==r){minv[o][rt]+=v;return;}int m=(l+r>>1);if(p<=m) update(o,p,v,lson);else update(o,p,v,rson);minv[o][rt]=min(minv[o][rt<<1],minv[o][rt<<1|1]);
}
int query(int o,int ql,int qr,int rt,int l,int r)
{if(ql<=l&&r<=qr) return minv[o][rt];int m=(l+r>>1);int res=2147483647;if(ql<=m) res=min(res,query(o,ql,qr,lson));if(m<qr) res=min(res,query(o,ql,qr,rson));return res;
}
void work(int l,int r,int f){if(l>=r){return;}int L=pos[query(l&1,ma[l],(l%2 == r%2) ? ma[r] : ma[r-1],1,1,n/2)];int R=pos[query((L+1)&1,ma[L+1],((L+1)%2 == r%2) ? ma[r] : ma[r-1],1,1,n/2)];pai[a[L]]=a[R];AddEdge(a[f],a[L]);work(l,L-1,f);work(L+1,R-1,L);work(R+1,r,f);
}
int main(){
//  freopen("c.in","r",stdin);scanf("%d",&n);for(int i=1;i<=n;++i){scanf("%d",&a[i]);pos[a[i]]=i;update(i&1,i/2+(i&1),a[i],1,1,n/2);ma[i]=i/2+(i&1);}if(n==2){printf("%d %d\n",a[1],a[2]);return 0;}work(1,n,0);for(int i=first[0];i;i=nex[i]){Heap.push(v[i]);}while(!Heap.empty()){int U=Heap.top(); Heap.pop();cnt+=2;printf("%d %d%c",U,pai[U],cnt==n ? '\n' : ' ');for(int i=first[U];i;i=nex[i]){Heap.push(v[i]);}}return 0;
}

转载于:https://www.cnblogs.com/autsky-jadek/p/7296626.html

【递归】【线段树】【堆】AtCoder Regular Contest 080 E - Young Maids相关推荐

  1. AtCoder Regular Contest 080

    手贱去开了abc,这么无聊.直接arc啊 C - 4-adjacent Time limit : 2sec / Memory limit : 256MB Score : 400 points Prob ...

  2. AtCoder Regular Contest 061 E - Snuke‘s Subway Trip(建图 + dijkstra最短路 / 0/1bfs / 并查集)

    AtCoder Regular Contest 061 E - Snuke's Subway Trip problem 洛谷翻译 my idea 最近一直在做网络流,所以一读这题后,我就想到了最小费用 ...

  3. NOMURA Programming Contest 2021(AtCoder Regular Contest 121)

    文章目录 A - 2nd Greatest Distance B - RGB Matching C - Odd Even Sort D - 1 or 2 E - Directed Tree F - L ...

  4. AtCoder Regular Contest 065

    AtCoder Regular Contest 065 C - Daydream Score : 300300300 points 倒着来就行了,正着来会产生歧义匹配,dreamer,dreamdre ...

  5. AtCoder Regular Contest 100 D - Equal Cut 思维 + 前缀和

    传送门 文章目录 题意: 思路: 题意: 给你一个数组aaa,你要将其分成四份,让这四份中和的最大值−-−最小值最小,输出这个最小值. n≤2e5,ai≤1e9n\le2e5,a_i\le1e9n≤2 ...

  6. AtCoder Regular Contest 100 E - Or Plus Max Sos dp

    传送门 文章目录 题意: 思路: 题意: 给你一个长度为2n2^n2n的数组,让你对于所有的1≤k≤2n−11\le k\le 2^n-11≤k≤2n−1求最大的ai+aj,0≤i<j≤2n−1 ...

  7. AtCoder题解——AtCoder Regular Contest 107——B - Quadruple

    题目相关 题目链接 AtCoder Regular Contest 107 B 题,https://atcoder.jp/contests/arc107/tasks/arc107_b. Problem ...

  8. AtCoder Regular Contest 120 C - Swaps 2 线段树模拟

    传送门 文章目录 题意: 思路: 题意: 给你两个序列a,ba,ba,b,每次可以执行一个操作:将a[i]a[i]a[i]与a[i+1]a[i+1]a[i+1]交换,且让交换后的a[i]+1,a[i+ ...

  9. Atcoder Regular contest 085F NRE 线段树+DP

    题意:给你两个序列,a全部为0,b给出,给出一些区间,可以把a上的这些区间变为全1,要求操作以后两个序列对应位置不相同的个数最小,n<=2e5. 说实话这种区间操作很容易想到线段树,但是我没想到 ...

最新文章

  1. python基础练习(十)
  2. 蓝桥备赛第三周 倍增+贪心+素数+约数
  3. Jquery 禁用元素的所有属性
  4. Vue父组件使用子组件时,需要携带参数,函数内如何获取子组件给的值
  5. linux的基础知识——本地套接字
  6. ExtJS和AngularJS比较
  7. ffmpeg sws_scale函数详解
  8. vue与外部html通信,VUE页面实现加载外部HTML方法
  9. 51nod1255【贪心-栈的应用】
  10. TIOBE 6 月编程语言排行榜:Java 放缓,C 复兴了!
  11. LayaAir graphics 矢量绘图之 圆形与扇形
  12. html页面小宠物代码大全,宠物店网页设计html代码
  13. 女生可以做软件测试吗?
  14. obs多推流地址_腾讯推流直播教程OBS下载、安装、使用
  15. (翻译)9种清晰直观的图标应用原则
  16. Android/IOS 实现接触NFC自动跳转到App,如果未安装App,则跳转到应用市场
  17. cisp含金量怎么样?
  18. pg数据库插件timescale时序库使用记录
  19. pacemaker+corosync+pg13
  20. 海康威视工业相机SDK二次开发(VS+Opencv+QT+海康SDK+C++)(一)

热门文章

  1. flutter中list相关操作汇总(有这一篇就够啦)
  2. dart - 如何从Dart中的列表中找到最小值和最大值
  3. jvm在windows和linux,理解JVM如何使用Windows和Linux上的本机内存
  4. 喜讯丨神策数据加入北京信创工委会!
  5. ansible配置详解及基本示例
  6. Confluence 6 启用远程 API
  7. Intellij IDEA 的使用
  8. TestNG测试带参构造函数的类
  9. ionic开发ios app
  10. 评 成功编SaaS的 10 大技巧