1 条题解
-
0
自动搬运
来自洛谷,原作者为

kczno1
**搬运于
2025-08-24 21:49:33,当前版本为作者最后更新于2017-02-11 16:55:12,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
noip双栈排序加强版。
如果存在k使得ak<ai<aj且k>j>i,那么i,j不能入一个栈。
i<->j连一条边,之后跑二分图染色,优先给小的染黑色,表示进第一个栈。
我们可以预处理m[i]=min{a[i+1..n]}
对每个j,找ai<aj且ai>m[j]的。
然而我们不能把边都连出来,因为会是n^2。
我们想办法只连出一些生成树,染色之后模拟判断一下行不行。
方法就是每连了两个块就并成一个块,并且用可并堆维护块内最小ai。
因为m是单调增的,如果最小ai<=m,就弹出。
之后我们再用一个堆维护所有块里面最小ai最小的块,每次取出,如果满足ai<aj就连边,合并。
时间nlogn。
(好久没打堆了233)
#include<cstdio> #include<algorithm> using std::swap; #define ch_top 10000000 char ch[ch_top],*now_w=ch-1; #define print(x) *++now_w=x; #define chmin(x,y) {if(x>y)x=y;} #define N 101000 int a[N],m[N];//m[i]=i->n min int t[N]; struct edge { int to,next; }l[10000000];int e; #define add_e(x,y) l[++e]=(edge){y,t[x]};t[x]=e; bool vis[N],col[N];//col[i]=1 第一个栈 int q1[N],t1,q2[N],t2; int n; int head[N],next[N]; int h[N<<1],top; void dfs(int x,bool now) { if (vis[x]) { if (col[x]!=now) {puts("NIE");exit(0);} } else { vis[x]=1;col[x]=now; for (int i=t[x];i;i=l[i].next) dfs(l[i].to,now^1); } } void move() { for (int i=1,j;(j=i<<1)<=top;) { if (j<top&&a[h[j]]>a[h[j+1]]) ++j; if (a[h[i]]<a[h[j]]) break ; swap(h[i],h[j]);i=j; } } void push(int x) { h[++top]=x; for (int i=top,j;i>1;) { if (a[h[i]]>=a[h[j=i>>1]]) break; swap(h[i],h[j]);i=j; } } void merge(int &x,int y) { if (a[x]<a[y]) { next[y]=head[x];head[x]=y; } else { next[x]=head[y];head[y]=x; x=y; } } void merges(int &x) { int y=next[x],r; while (y) { r=next[y]; merge(x,y); y=r; } next[x]=0; } int main() { freopen("1.in","r",stdin); int i,j; scanf("%d",&n); for (i=1;i<=n;++i) {scanf("%d",a+i);m[i]=a[i];} for (i=n;--i;) chmin(m[i],m[i+1]) h[top=1]=1; a[0]=N+1; m[n+1]=N; int p; for (i=2;i<=n;++i) { int rt=i; for (;a[p=h[1]]<a[i];) { while (a[p]<=m[i+1]) merges(p=head[p]); if(a[p]<a[i]) {add_e(i,p);add_e(p,i);merge(rt,p);h[1]=h[top--]; } else h[1]=p; move(); } push(rt); } int now=1; print('T') print('A') print('K') print('\n') for (i=1;i<=n;++i) { if (!vis[i]) dfs(i,1); if (col[i]) {q1[++t1]=i;print('1') } else {q2[++t2]=i;print('2') } print(' ') while (a[q1[t1]]==now||a[q2[t2]]==now) { if (a[q1[t1]]==now++) { --t1; } else { --t2; } } } if (now<=n) puts("NIE"); else fwrite(ch,1,now_w-ch,stdout); }
- 1
信息
- ID
- 2573
- 时间
- 1000ms
- 内存
- 125MiB
- 难度
- 6
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者