AtCoder Regular Contest 080 E
来源:互联网 发布:mac luajit 安装 编辑:程序博客网 时间:2024/06/06 20:03
http://arc080.contest.atcoder.jp/tasks/arc080_c
其实细想其本质是一道拓扑序的题,选了当前点,才能选分裂出的三段。
#include<bits/stdc++.h>#define pb push_back #define mp make_pairusing namespace std;const int maxn=2e5+7;typedef long long ll;struct My{ int l,r; pair<int,int> p; My(int L,int R,pair<int,int>P) :l(L),r(R),p(P) {}};bool operator<(const My &a,const My &b){ if(a.p>b.p) return 1; return 0;}priority_queue<My>q;vector<pair<int,int> >ans;vector<int>b1,b2;int n;int h1,h2;int a[maxn];int pos[maxn];//int f[maxn];struct node{ int l,r; int min; void update(int v) { min+=v; }}tree[maxn*4],tree2[maxn*4];void push_up(int o){ tree[o].min=min(tree[o<<1].min,tree[o<<1|1].min);}void build(int l,int r,int o){ tree[o].l=l;tree[o].r=r; if(l==r) { tree[o].min=b1[l]; } else { int mid=(l+r)/2; build(l,mid,o<<1); build(mid+1,r,o<<1|1); push_up(o); }}void update(int p,int x,int o){}int qmin;void query(int ql,int qr,int o){ int l=tree[o].l,r=tree[o].r; if(ql<=l&&r<=qr) { qmin=min(qmin,tree[o].min); } else { int mid=(l+r)/2; if(ql<=mid) query(ql,qr,o<<1); if(qr>mid) query(ql,qr,o<<1|1); }}//////////////////////////////////////////////////////////////////////////////void push_up2(int o){ tree2[o].min=min(tree2[o<<1].min,tree2[o<<1|1].min);}void build2(int l,int r,int o){ tree2[o].l=l;tree2[o].r=r; if(l==r) { tree2[o].min=b2[l]; } else { int mid=(l+r)/2; build2(l,mid,o<<1); build2(mid+1,r,o<<1|1); push_up2(o); }}void update2(int p,int x,int o){}void query2(int ql,int qr,int o){ int l=tree2[o].l,r=tree2[o].r; if(ql<=l&&r<=qr) { qmin=min(qmin,tree2[o].min); } else { int mid=(l+r)/2; if(ql<=mid) query2(ql,qr,o<<1); if(qr>mid) query2(ql,qr,o<<1|1); }}int Q1(int l,int r){ l=(l+1)/2; r=(r+1)/2; qmin=1e9; query(l,r,1); return pos[qmin];}int Q2(int l,int r){ l=(l)/2; r=(r)/2; qmin=1e9; query2(l,r,1); return pos[qmin];}int num1,num2;pair<int,int> work(int l,int r){ if(l+1==r) { return mp(a[l],a[r]); } int i,j,k; if(l%2==1) num1=Q1(l,r); else num1=Q2(l,r); if(l%2==1) num2=Q2(num1+1,r); else num2=Q1(num1+1,r); //ans.pb(mp(a[num1],a[num2])); /* work(l,num1-1); work(num2+1,r); work(num1+1,num2-1); */ return mp(a[num1],a[num2]);}void doit(){ q.push(My(1,n,work(1,n))); while(!q.empty()) { My now=q.top(); q.pop(); ans.pb(now.p); int l,r,l1,r1; l=now.l; r=now.r; l1=pos[now.p.first]; r1=pos[now.p.second]; if(l<l1-1) q.push(My(l,l1-1,work(l,l1-1))); if(l1+1<r1-1) q.push(My(l1+1,r1-1,work(l1+1,r1-1))); if(r1+1<r) q.push(My(r1+1,r,work(r1+1,r))); }}int main(){ int i,j,k; scanf("%d",&n); b1.pb(0); b2.pb(0); for(i=1;i<=n;++i) { scanf("%d",&a[i]); pos[a[i]]=i; if(i&1) { b1.pb(a[i]); } else b2.pb(a[i]); } h1=b1.size()-1; h2=b2.size()-1; build(1,h1,1); build2(1,h2,1); doit(); int len=ans.size(); for(i=0;i<len-1;++i) { printf("%d %d ",ans[i].first,ans[i].second); } printf("%d %d\n",ans[len-1].first,ans[len-1].second); return 0;}
另解:斌大爷的分块
阅读全文
0 0
- AtCoder Regular Contest 080 E
- AtCoder Regular Contest 080 E
- AtCoder Regular Contest 077 E
- AtCoder Regular Contest 077 E
- AtCoder Regular Contest 075 E
- AtCoder Regular Contest 079-E
- AtCoder regular contest 081 E
- 【树状数组】AtCoder Regular Contest 075 E
- 【Atcoder】Regular Contest 079 D E
- AtCoder Regular Contest 079 C D E
- AtCoder Regular Contest 082-E-ConvexScore
- AtCoder Regular Contest 080-C
- AtCoder Regular Contest 080-D
- Atcoder Regular Contest 080 CDEF
- AtCoder Regular Contest 080 C , D
- AtCoder Regular Contest 080 CD题
- Atcoder Regular Contest 072 E Alice in Linear Land
- AtCoder Regular Contest 077
- 二叉树总结
- Node.js环境变量配置
- mac 启用wifi调试android 程序
- 查找不到根节点的不可见的物体,transform.Find 与GameObject.Find区别
- Java基础
- AtCoder Regular Contest 080 E
- Java对象引用
- Java封装
- Palindrome Linked List
- nginx安装以及错误处理
- 关于求字符串长度的问题,(strlen(),str.size()和str.length())
- Java编写程序(1)
- 安装sipp时遇到的小问题
- Java编写程序(2)