AtCoder Regular Contest 080 E - Young Maids [拓扑序+分治+奇偶rmq]||[分块]
2017-08-08 12:00
543 查看
http://arc080.contest.atcoder.jp/tasks/arc080_c
其实细想其本质是一道拓扑序的题,选了当前点,才能选分裂出的三段。
另解:斌大爷的分块
其实细想其本质是一道拓扑序的题,选了当前点,才能选分裂出的三段。
#include<bits/stdc++.h> #define pb push_back #define mp make_pair using 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) { t b59f ree2[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; }
另解:斌大爷的分块
相关文章推荐
- AtCoder Regular Contest 080 E - Young Maids
- 【递归】【线段树】【堆】AtCoder Regular Contest 080 E - Young Maids
- AtCoder Regular Contest 080 E - Young Maids 贪心+堆+RMQ
- AtCoder Regular Contest 080 F - Prime Flip 线性筛+匈牙利算法
- AtCoder Regular Contest 080 C , D
- 【AtCoder Regular Contest 080E】Young Maids [堆][线段树]
- [AtCoder Regular Contest 080] F: Prime Flip (arc080F)
- (线段树/贪心)AtCoder Regular Contest 080 E : Old Maid
- AtCoder Regular Contest 080-C - 4-adjacent
- AtCoder Regular Contest 080 C - 4-adjacent
- AtCoder Regular Contest 080 D - Grid Coloring
- AtCoder Regular Contest 080-D - Grid Coloring
- AtCoder Regular Contest 080 [CDEF]
- AtCoder Regular Contest 080 F - Prime Flip 二分图匹配+哥德巴赫猜想
- AtCoder Regular Contest 080 CD题
- AtCoder Regular Contest 080 E - Young Maids(线段树+优先队列)
- Atcoder Regular Contest 080 F Prime Flip
- AtCoder Regular Contest 075 E - Meaningful Mean(树状数组)
- AtCoder Regular Contest 076 F - Exhausted (Hall's marriage theorem 或 贪心)
- [霍尔定理] AtCoder Regular Contest 076 F Exhausted?