当$S_{i}=S_{i+1}$时对$i$操作显然无意义,不妨强制不允许此类操作
构造排列$P_{i}$,初始等于$\{1,2,...,n\}$,当对$i$操作后交换$P_{i}$和$P_{i+1}$
结论:$S_{i}=[\min_{i\le j\le n}P_{j},\max_{1\le j\le i}P_{j}]$
考虑归纳,初始显然成立,考虑某次对$i$操作——
简单分析,也即求证$P_{i+1}\ne \min_{i\le j\le n}P_{j}$且$P_{i}\ne \max_{1\le j\le i+1}P_{j}$(这里的$P_{i}$仍是交换前的排列)
两者不成立的必要条件均为$P_{i}>P_{i+1}$,而此时显然$S_{i}=S_{i+1}$,与假设矛盾
换言之,问题即构造$P_{i}$,使得$L_{i}=\min_{i\le j\le n}P_{j}$且$R_{i}=\max_{1\le j\le i}P_{j}$,并最小化逆序对数
首先,可以确定确定$P_{i}=\begin{cases}L_{i}&(i=n\or L_{i}\ne L_{i+1})\\R_{i}&(i=1 \or R_{i}\ne R_{i-1})\end{cases}$
同时,简单判定合法性:无重复元素且不存在最小值过小/最大值过大(后者也保证了$L_{i}$和$R_{i}$单调不降)
然后,每一个$L_{i}$和$R_{i}$均已经存在$P_{j}$取到该值,即每一个位置仅还有$\in [L_{i},R_{i}]$的限制,根据两者的单调性,直接将剩余元素从小到大依次填入即可(填入时判定该限制,且这样也最小化逆序对数)
最终,简单统计逆序对数即可
时间复杂度为$o(n\log n)$,可以通过
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define N 500005 4 int n,L[N],R[N],P[N],vis[N],f[N]; 5 long long ans; 6 int lowbit(int k){ 7 return (k&(-k)); 8 } 9 void update(int k){ 10 while (k<=n){ 11 f[k]++; 12 k+=lowbit(k); 13 } 14 } 15 int query(int k){ 16 int ans=0; 17 while (k){ 18 ans+=f[k]; 19 k-=lowbit(k); 20 } 21 return ans; 22 } 23 int main(){ 24 scanf("%d",&n); 25 for(int i=1;i<=n;i++)scanf("%d%d",&L[i],&R[i]); 26 for(int i=1;i<=n;i++){ 27 if ((i==n)||(L[i]!=L[i+1]))P[i]=L[i]; 28 if ((i==1)||(R[i]!=R[i-1])){ 29 if ((P[i])&&(P[i]!=R[i])){ 30 printf("-1\n"); 31 return 0; 32 } 33 P[i]=R[i]; 34 } 35 } 36 for(int i=n,s=n+1;i;i--){ 37 if (P[i])s=min(s,P[i]); 38 if (s<L[i]){ 39 printf("-1\n"); 40 return 0; 41 } 42 } 43 for(int i=1,s=0;i<=n;i++){ 44 if (P[i])s=max(s,P[i]); 45 if (s>R[i]){ 46 printf("-1\n"); 47 return 0; 48 } 49 } 50 for(int i=1;i<=n;i++){ 51 if ((P[i])&&(vis[P[i]])){ 52 printf("-1\n"); 53 return 0; 54 } 55 vis[P[i]]=1; 56 } 57 for(int i=1,j=1;i<=n;i++) 58 if (!P[i]){ 59 while ((j<=n)&&(vis[j]))j++; 60 if ((j<L[i])||(j>R[i])){ 61 printf("-1\n"); 62 return 0; 63 } 64 vis[j]=1,P[i]=j; 65 } 66 for(int i=1;i<=n;i++){ 67 ans+=query(n)-query(P[i]); 68 update(P[i]); 69 } 70 printf("%lld\n",ans); 71 return 0; 72 }View Code