To infinity and beyond. -<Wall-E>
First of all, we can use the discretization + tree array to calculate the time complexity (n log n) of the number of reverse order pairs
For questions about the reverse order pair, we can first think of the characteristics of the reverse order pair:
Then for each inquiry (x,y) (x < y), the number on both sides has no effect. The number a[i] of interval (x,y) is discussed as follows:
a[i]<a[x] --ans
a[i]>a[x] ++ans
a[i]<a[y] ++ans
a[i]>a[y] --ans
At this time, I want to use block processing
For n-number blocks, what we need to do in each block is to determine how many blocks are more than a [x] or (a[y]) (this step can be treated equivalently (a tip))
Consider tree array
But at this time, it will be faster if we use block processing
For data weight block
ha[k][i] represents the number less than base*i in the k-th block number. At the same time, use pre[k][i] table to record the number of < = I & & > base * (I / base) in the k-th block number, so as to record the smaller intervals on both sides of the block
Code:
#Include < bits / STDC + +. H > / / block nesting using namespace std; const int maxn=500000; long long n,m,cnt,u,v,a[maxn],b[maxn],sum[maxn],ha[201][201],pre[201][20001],k1,k2,k3,block; long long query(int x) {long long ans=0; for (int i=x;i;i-=(i&-i)) ans+=sum[i]; return ans;} void add(int x) { for (int i=x;i<=maxn;i+=(i&-i)) sum[i]++;} int getblock(int x) { return (x-1)/block+1;} void change(int k,int zhi,int an) //Process the current block { int kzhi=getblock(zhi); for (int i=kzhi+1;i<=getblock(n);i++) ha[k][i]+=an; for (int i=zhi;i<=(kzhi)*block;i++) pre[k][i]+=an; } int ask(int l,int r,int zhi) { if (l>r) return 0; k1=getblock(l); k2=getblock(r); long long sum=0; if (k1==k2) { for (int i=l;i<=r;i++){if (zhi>b[i]) sum++; if (zhi>=b[i]) sum++; }} else { for (int i=l;i<=k1*block;i++) {{if (zhi>b[i]) sum++; if (zhi>=b[i]) sum++; }} for (int i=(k2-1)*block+1;i<=r;i++) {{if (zhi>b[i]) sum++; if (zhi>=b[i]) sum++; }} k3=getblock(zhi); for (int i=k1+1;i<k2;i++) { sum+=ha[i][k3]+pre[i][zhi]; } zhi--; k3=getblock(zhi); for (int i=k1+1;i<k2;i++) { sum+=ha[i][k3]+pre[i][zhi]; } } return (sum-(r-l+1)); } int main() { cin>>n; for (int i=1;i<=n;i++) {cin>>b[i]; a[i]=b[i]; } sort(a+1,a+1+n); for (int i=1;i<=n;i++) {b[i]=lower_bound(a+1,a+1+n,b[i])-a; //Discretization operation b[i]=n+1-b[i];} for (int i=1;i<=n;i++) { cnt+=query(b[i]-1); add(b[i]);} block=200; cout<<cnt<<endl; for (int i=1;i<=n;i++) { change(getblock(i),b[i],1);} cin>>m; for (int i=1;i<=m;i++) { cin>>u>>v; if (b[u]==b[v]) { cout<<cnt<<endl; continue;} if (u>v) swap(u,v); cnt+=ask(u+1,v-1,b[u]);//Find the number smaller than b[u] in u+1--v-1 interval and subtract the number larger than b[u] cnt-=ask(u+1,v-1,b[v]); if (b[u]>b[v]) cnt++; else cnt--; change(getblock(u),b[u],-1); change(getblock(v),b[v],-1); change(getblock(v),b[u],1); change(getblock(u),b[v],1); swap(b[u],b[v]); cout<<cnt<<endl; } }