[set]JZOJ 5947 初音未来
分析
一个序列交换相邻的两个数进行排序的话,最小次数就是逆序对个数,具体操作方法就是每次交换相邻逆序对。所以将排序过程变为交换相邻位置直到没有逆序对。记录哪些位置是逆序对。排序操作变为寻找区间内最靠左的逆序对并交换。这个过程可以用set维护。每次二分出逆序对的位置,如果再区间内,则交换之,并将两侧出现的新逆序对加入。
#include <iostream> #include <cstdio> #include <set> using namespace std; const int N=1.5e3+10; set<int> nxd; int a[N]; int n,m,L,R; int main() { freopen("miku.in","r",stdin); freopen("miku.out","w",stdout); scanf("%d%d%d%d",&n,&m,&L,&R); for (int i=1;i<=n;i++) scanf("%d",&a[i]); for (int i=2;i<=n;i++) if (a[i]<a[i-1]) nxd.insert(i-1); for (int i=1;i<=m;i++) { int l,r; scanf("%d%d",&l,&r); for (int x=*nxd.lower_bound(l);x<r;x=*nxd.lower_bound(l)) { swap(a[x],a[x+1]);nxd.erase(x); if (a[x]<a[x-1]) nxd.insert(x-1); if (a[x+2]<a[x+1]) nxd.insert(x+1); } } for (int i=L;i<=R;i++) printf("%d ",a[i]); }
在日渐沉没的世界里,我发现了你。