题目大意:数据范围10W的双栈排序..双栈排序是啥呢?给你一个序列和两个栈,每次你可以把序列头入到两个栈的任意一个,或者把两个栈的任意一个弹出到最终序列,最后要求最终序列是有序的,求一种字典序最小的入栈方案
感觉自己应该是写不明白...日后如果有兴趣再来填坑吧..
先附上多年以前
vfk写的题解,非常详细
再附上我的代码...
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#define N 100010
using namespace std;
int a[N],fan[N],pre[N],L[N];
int l[N<<2],r[N<<2],h[N<<2],cnt;
struct ppp{int mx,mxb;}W[N<<2];
ppp operator +(const ppp &x,const ppp &y)
{
ppp ret;
ret.mx=max(x.mx,y.mx);
if(x.mx>y.mx) ret.mxb=x.mxb;
else ret.mxb=y.mxb;
return ret;
}
void pup(int x)
{
W[x]=W[x<<1]+W[x<<1|1];
}
void build(int now,int ll,int rr)
{
l[now]=ll;r[now]=rr;
cnt++;h[now]=cnt;
if(ll==rr)
{
W[now]=(ppp){a[ll],ll};
return;
}
int mid=(ll+rr)>>1;
build(now<<1,ll,mid);
build(now<<1|1,mid+1,rr);
pup(now);
}
int bef[N*30],nxt[N*30],w[N*30];
int S[N],T[N];
void change(int now,int ll,int rr,int v)
{
if(l[now]==ll&&r[now]==rr)
{
cnt++;
w[cnt]=v;
nxt[cnt]=nxt[h[now]];
bef[cnt]=h[now];
bef[nxt[h[now]]]=cnt;
nxt[h[now]]=cnt;
return;
}
int mid=(l[now]+r[now])>>1;
if(rr<=mid) change(now<<1,ll,rr,v);
else if(ll>mid) change(now<<1|1,ll,rr,v);
else change(now<<1,ll,mid,v),change(now<<1|1,mid+1,rr,v);
}
void change1(int now,int x)
{
if(l[now]==r[now]) {W[now]=(ppp){0,0};return;}
int mid=(l[now]+r[now])>>1;
if(x<=mid) change1(now<<1,x);
else change1(now<<1|1,x);
pup(now);
}
int col[N];
void erase(int x)
{
int i;
change1(1,x);
for(i=S[x];i<=T[x];i++)
{
bef[nxt[i]]=bef[i];
nxt[bef[i]]=nxt[i];
}
}
ppp check1(int now,int ll,int rr)
{
if(ll==l[now]&&rr==r[now]) return W[now];
int mid=(l[now]+r[now])>>1;
if(rr<=mid) return check1(now<<1,ll,rr);
else if(ll>mid) return check1(now<<1|1,ll,rr);
else return check1(now<<1,ll,mid)+check1(now<<1|1,mid+1,rr);
}
int check(int now,int x)
{
if(nxt[h[now]]&&w[nxt[h[now]]]<a[x]) return fan[w[nxt[h[now]]]];
if(l[now]==r[now]) return -1;
int mid=(l[now]+r[now])>>1;
if(x<=mid) return check(now<<1,x);
else return check(now<<1|1,x);
}
int getedge(int x)
{
ppp tmp=check1(1,x,L[x]);
if(tmp.mx>a[x]) return tmp.mxb;
return check(1,x);
}
void dfs(int x,int c)
{
col[x]=c;
erase(x);
while(1)
{
int y=getedge(x);
if(y==-1) break;
dfs(y,3-c);
}
}
int n;
int s[3][N],t[3];
bool pcan()
{
int i,j,x;
for(i=1;i<=n;i++)
{
x=col[i];
while(t[x]&&L[s[x][t[x]]]<=i) t[x]--;
if(t[x]&&a[s[x][t[x]]]<a[i]) return puts("NIE"),false;
t[x]++;s[x][t[x]]=i;
}
return puts("TAK"),true;
}
int main()
{
scanf("%d",&n);
int i,j,x,y;
for(i=1;i<=n;i++)
{
scanf("%d",&a[i]);
fan[a[i]]=pre[a[i]]=i;
}
for(i=1;i<=n;i++)
pre[i]=max(pre[i],pre[i-1]);
for(i=1;i<=n;i++)
L[fan[i]]=pre[i];
build(1,1,n);
for(i=n;i>=1;i--)
{
x=fan[i];
S[x]=cnt+1;
change(1,x,L[x],i);
T[x]=cnt;
}
for(i=1;i<=n;i++)
if(!col[i])
dfs(i,1);
if(pcan())
{
printf("%d",col[1]);
for(i=2;i<=n;i++)
printf(" %d",col[i]);
}
}