这个题很绕,记数字i前面有cns[i]个数字比他大,逆序对个数就是sigmi cns[i]
反转k次就是让cns[i] - k (i>=1 && i <= n) 而且cns[i]不能有负数
利用两个线段树维护一下,就是有点绕。。。。
#include<iostream> #include<cstring> #include<queue> #include<cstdio> #include<algorithm> using namespace std; typedef long long ll ; const int maxn = 2e5+11; struct Node{ ll ans,sum; }tree[4][maxn*4]; int update(int id,int node,int be,int en,int i,int val){ int mid = be + en >> 1; int l = node*2; int r = node*2+1; if(be == en){ tree[id][node].ans += val; if(val > 0) tree[id][node].sum += 1; if(val < 0) tree[id][node].sum -= 1; return 0; } if(i <= mid) update(id,l,be,mid,i,val); else update(id,r,mid+1,en,i,val); tree[id][node].ans = tree[id][l].ans + tree[id][r].ans; tree[id][node].sum = tree[id][l].sum + tree[id][r].sum; return 0; } ll ask(int id,int node,int be,int en,int LL,int RR){ int mid = be + en >> 1; int l = node*2; int r = node*2+1; if(LL <= be && en <= RR){ return tree[id][node].ans; } ll a = 0; if(LL <= mid) a += ask(id,l,be,mid,LL,RR); if(RR > mid) a += ask(id,r,mid+1,en,LL,RR); return a; } ll ask2(int id,int node,int be,int en,int LL,int RR){ int mid = be + en >> 1; int l = node*2; int r = node*2+1; if(LL <= be && en <= RR){ return tree[id][node].sum; } ll a = 0; if(LL <= mid) a += ask2(id,l,be,mid,LL,RR); if(RR > mid) a += ask2(id,r,mid+1,en,LL,RR); return a; } int list[maxn]; ll cns[maxn]; int main(){ int n,m; scanf("%d %d",&n,&m); for(int i=1;i<=n;i++){ scanf("%d",&list[i]); ll a = 0; if(list[i] != n) a = ask(0,1,1,n,list[i]+1,n); cns[list[i]] = a; update(2,1,1,n,list[i],a); if(a != 0) update(1,1,1,n,a,a); update(0,1,1,n,list[i],1); } while(m--){ int x,y; scanf("%d%d",&x,&y); if(x == 1){ if(list[y] < list[y+1]){ ll ans = cns[list[y]]; if(ans != 0) update(1,1,1,n,ans,-ans); update(1,1,1,n,ans+1,ans+1); cns[list[y]]++; update(2,1,1,n,list[y],1); } else{ ll ans = cns[list[y+1]]; update(1,1,1,n,ans,-ans); if(ans - 1 != 0) update(1,1,1,n,ans-1,ans-1); cns[list[y+1]]--; update(2,1,1,n,list[y+1],-1); } swap(list[y],list[y+1]); } else{ ll ans = 0; if(y == 0){ ans = ask(2,1,1,n,1,n); } else if(y >= n){ ans = 0; } else{ ans = ask(2,1,1,n,1,n) - ask(1,1,1,n,1,y) - ask2(1,1,1,n,y+1,n)*y; // cout<<ask(2,1,1,n,1,n)<<" "<<ask(1,1,1,n,1,y)<<" "<<ask2(1,1,1,n,y+1,n)<<endl; } printf("%lld\n",ans); } } return 0; }