1. 程式人生 > >Atcoder AGC014F : Strange Sorting(Treap)

Atcoder AGC014F : Strange Sorting(Treap)

傳送門

題解:
老年選手不會正解,只能用暴力卡卡常了。

這樣的操作過不了多久就是連續的幾段在挪,用Treap+二分即可水過。

#include <bits/stdc++.h>
using namespace std;
const int RLEN=1<<18|1;
inline char nc() {
	static char ibuf[RLEN],*ib,*ob;
	(ib==ob) && (ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));
	return (ib==ob) ? -1 : *ib++;
} inline int rd() { char ch=nc(); int i=0,f=1; while(!isdigit(ch)) {if(ch=='-')f=-1; ch=nc();} while(isdigit(ch)) {i=(i<<1)+(i<<3)+ch-'0'; ch=nc();} return i*f; } const int N=2e5+50; int n,a[N],nowmx; inline unsigned int unit() {static unsigned int x=19260817; x^=(x<<13); x^=(x>>
17); x^=(x<<5); return x;} inline int Max(int x,int y) {return (x>y) ? x : y;} struct node { node *lc,*rc; unsigned int pri; int val,sze,mx,all,tag; node() : lc(NULL),rc(NULL),pri(unit()),sze(0),mx(0),all(1) {} inline void upt() { mx=Max(Max(rc->mx,lc->mx),val); sze=lc->sze+
rc->sze+1; all=lc->all&rc->all&tag; } } *rt,*nowrt,Pool[N],*pool=Pool,*null=pool; typedef pair <node*,node*> pii; inline node* merge(node *x,node *y) { if(y==null) return x; if(x==null) return y; if(x->pri>y->pri) { x->rc=merge(x->rc,y); x->upt(); return x; } else { y->lc=merge(x,y->lc); y->upt(); return y; } } inline pii split(node *x,int sze) { if(x==null) return pii(null,null); if(x->lc->sze>=sze) { pii tr=split(x->lc,sze); x->lc=tr.second; x->upt(); return pii(tr.first,x); } else { pii tr=split(x->rc,sze-x->lc->sze-1); x->rc=tr.first; x->upt(); return pii(x,tr.second); } } inline void Merge(node *&x,node *y) { if(y==null) {return;} if(x==null) {x=y; return;} node *t=x; while(t->rc!=null) t=t->rc; node *t2=y; static node* stk[N]; int top=0; while(t2->lc!=null) stk[++top]=t2, t2=t2->lc; t2->tag=(t2->val>t->val) ? 1 : 0; t2->upt(); while(top) stk[top--]->upt(); x=merge(x,y); } inline pii split_val(node *x,int lim) { if(x==null) return pii(null,null); if(Max(x->val,x->lc->mx)<lim) { pii tr=split_val(x->rc,lim); x->rc=tr.first; x->upt(); return pii(x,tr.second); } else { pii tr=split_val(x->lc,lim); x->lc=tr.second; x->upt(); return pii(tr.first,x); } } inline pii split_all(node *x) { if(x==null) return pii(null,null); if(!(x->lc->all&x->tag)) { pii tr=split_all(x->lc); x->lc=tr.second; x->upt(); return pii(tr.first,x); } else { pii tr=split_all(x->rc); x->rc=tr.first; x->upt(); return pii(x,tr.second); } } inline node* find_nxt(int lim) { pii tr=split_val(rt,lim); pii tr2=split_all(tr.second); Merge(nowrt,tr.first); rt=tr2.second; return tr2.first; } inline node* newnode() { node *t=++pool; t->lc=t->rc=null; return t; } node* q[N]; int qt; int main() { n=rd(); rt=null; nowmx=n; for(int i=1;i<=n;i++) a[i]=rd(); for(int i=0;i<=n;i++) { node *t=newnode(); t->val=a[i]; t->sze=1; t->mx=a[i]; t->all=(i ? (a[i]>a[i-1]) : 1); t->tag=t->all; rt=merge(rt,t); } int step=0; while(!rt->all) { ++step; int mxval=1, pos=0; qt=0; nowrt=null; while(mxval<nowmx) mxval=(q[++qt]=find_nxt(mxval))->mx; Merge(nowrt,rt); rt=nowrt; for(int i=1;i<=qt;i++) Merge(rt,q[i]); while(nowmx>3) { pii tr=split(rt,nowmx); if(tr.second->val==nowmx) rt=tr.first, --nowmx; else {rt=merge(tr.first,tr.second); break;} } } cout<<step<<'\n'; }