【題解】CF1585D Yet Another Sorting Problem
阿新 • • 發佈:2021-12-20
題意
給定一個長度為 \(n\) 的陣列 \(a\)。
每次操作可以選擇三個數進行迴圈右移。
詢問是否可以將陣列排序。
Sol
若陣列中存在相同的數,那麼顯然有解。
再考慮沒有數相同的情況。
由於是挑 \(3\) 個數迴圈右移,那麼每次逆序對的數量會減少 \(2\)。
那麼統計一下逆序對即可。
我用的是樹狀陣列。時間複雜度 \(O(n \log n)\),存在 \(O(n)\) 做法。
Code
//LYC_music yyds! #include<bits/stdc++.h> #define IOS ios::sync_with_stdio(0) #define lowbit(x) (x&(-x)) using namespace std; inline char gc() { static char buf[1000000],*p1=buf,*p2=buf; return p1==p2&&(p2=(p1=buf)+fread(buf,1,1000000,stdin),p1==p2)?EOF:*p1++; } int read() { int pos=1,num=0; char ch=getchar(); while (!isdigit(ch)) { if (ch=='-') pos=-1; ch=getchar(); } while (isdigit(ch)) { num=num*10+(int)(ch-'0'); ch=getchar(); } return pos*num; } void write(int x) { if (x<0) { putchar('-'); write(-x); return; } if (x>=10) write(x/10); putchar(x%10+'0'); } void writesp(int x) { write(x); putchar(' '); } void writeln(int x) { write(x); putchar('\n'); } const int N=5e5+10; bool vis[N],flag; int n,a[N],tree[N]; inline void add(int x,int y) { for (;x<=n;x+=lowbit(x)) tree[x]+=y; } inline int query(int x) { int res=0; for (;x;x-=lowbit(x)) res+=tree[x]; return res; } signed main() { int T=read(); while (T--) { n=read(); flag=0; for (int i=1;i<=n;i++) vis[i]=0,tree[i]=0; for (int i=1;i<=n;i++) { a[i]=read(); if (vis[a[i]]) flag=1; vis[a[i]]=1; } if (flag) { puts("YES"); continue; } int res=0; for (int i=1;i<=n;i++) { res+=query(n)-query(a[i]); add(a[i],1); } if (res&1) puts("NO"); else puts("YES"); } }