位置的嵌套把我弄晕了。。。总感觉多写了一层
/* 首先要找到一种满足条件的排列方式 给所有段按(左端点,右端点)升序排序,然后分配位置 从左到右扫描位置i,把左端点<i的所有Seg放入优先队列 优先队列每次取出右端点最小的 然后考虑两个段是否可以交换顺序:设段[l,r]被分配的位置是x 那么和他交换的段位置只能在[l,x-1],[x+1,r]里找,只要找到[l,x-1]位置右端点最大值,[x+1,r]位置左端点最小值 判能否越过x即可 */ #include<bits/stdc++.h> using namespace std; #define N 200005 int n; struct Seg{ int l,r,id; bool operator>(Seg a)const { return r>a.r; } }s[N],ss[N]; int cmp(Seg a,Seg b){return a.l<b.l;} priority_queue<Seg,vector<Seg>,greater<Seg> >pq; int ans1[N],ans2[N],tmp[N]; #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 int mx[N<<2],mi[N<<2]; void update1(int pos,int id,int l,int r,int rt){ if(l==r){mx[rt]=id;return;} int m=l+r>>1; if(pos<=m)update1(pos,id,lson); else update1(pos,id,rson); if(!mx[rt<<1]){ mx[rt]=mx[rt<<1|1];return; } if(!mx[rt<<1|1]){ mx[rt]=mx[rt<<1];return; } int id1=mx[rt<<1],id2=mx[rt<<1|1]; if(ss[id1].r>=ss[id2].r)mx[rt]=id1; else mx[rt]=id2; } int query1(int L,int R,int l,int r,int rt){ if(L>R)return 0; if(L<=l && R>=r)return mx[rt]; int m=l+r>>1,res=0; if(L<=m)res=query1(L,R,lson); if(R>m){ if(!res)res=query1(L,R,rson); else { int res2=query1(L,R,rson); if(ss[res].r<ss[res2].r)res=res2; } } return res; } void update2(int pos,int id,int l,int r,int rt){ if(l==r){mi[rt]=id;return;} int m=l+r>>1; if(pos<=m)update2(pos,id,lson); else update2(pos,id,rson); if(!mi[rt<<1]){ mi[rt]=mi[rt<<1|1];return; } if(!mi[rt<<1|1]){ mi[rt]=mi[rt<<1];return; } int id1=mi[rt<<1],id2=mi[rt<<1|1]; if(ss[id1].l<=ss[id2].l)mi[rt]=id1; else mi[rt]=id2; } int query2(int L,int R,int l,int r,int rt){ if(L>R)return 0; if(L<=l && R>=r)return mi[rt]; int m=l+r>>1,res=0; if(L<=m)res=query2(L,R,lson); if(R>m){ if(!res)res=query2(L,R,rson); else { int res2=query2(L,R,rson); if(ss[res].l>ss[res2].l)res=res2; } } return res; } int pos[N]; int main(){ cin>>n; for(int i=1;i<=n;i++){ cin>>s[i].l>>s[i].r; s[i].id=i; } memcpy(ss,s,sizeof s); sort(s+1,s+1+n,cmp); int p=1; for(int i=1;i<=n;i++){ while(p<=n && s[p].l<=i){ pq.push(s[p]); ++p; } Seg now=pq.top();pq.pop(); ans1[i]=now.id; } //for(int i=1;i<=n;i++)pos[ans[i].id]=i; for(int i=1;i<=n;i++){ update1(i,ans1[i],1,n,1); update2(i,ans1[i],1,n,1); } int flag=0,p1,p2; memcpy(ans2,ans1,sizeof ans1); for(int i=1;i<=n;i++){ int L1=ss[ans1[i]].l,R1=i-1; int L2=i+1,R2=ss[ans1[i]].r; int res1=query1(L1,R1,1,n,1); int res2=query2(L2,R2,1,n,1); if(res1 && ss[res1].r>=i){ flag=1; p1=ans1[i],p2=res1; break; } if(res2 && ss[res2].l<=i){ flag=1; p1=ans1[i],p2=res2; break; } } if(flag){ puts("NO"); for(int i=1;i<=n;i++) tmp[ans1[i]]=i; for(int i=1;i<=n;i++)cout<<tmp[i]<<" "; puts(""); swap(tmp[p1],tmp[p2]);//1 4 2 3 for(int i=1;i<=n;i++)cout<<tmp[i]<<" "; puts(""); }else { puts("YES"); for(int i=1;i<=n;i++) tmp[ans1[i]]=i; for(int i=1;i<=n;i++)cout<<tmp[i]<<" "; puts(""); } }